重命名ActiveRecord/Rails的created_at,updated_at列

Rai*_*ing 13 activerecord timestamp ruby-on-rails

我想重命名timestamp.rb中定义的timestamp列.timestamp.rb的方法可以被覆盖吗?在应用程序中必须要做的是使用带有覆盖方法的模块.

Tad*_*kas 27

我认为NPatel的方法是一种正确的方法,但如果您只需要在单个模型上更改#created_at,它就会做得太多.由于Timestamp模块包含在每个AR对象中,因此您可以按模型覆盖它,而不是全局覆盖它.

<= Rails 5.0

class User < ActiveRecord::Base
  ...
  private
  def timestamp_attributes_for_create
    super << :registered_at
  end
end
Run Code Online (Sandbox Code Playgroud)

Rails~> 5.1

  private_class_method
  def self.timestamp_attributes_for_create
    # only strings allowed here, symbols won't work, see below commit for more details
    # https://github.com/rails/rails/commit/2b5dacb43dd92e98e1fd240a80c2a540ed380257 
    super << 'registered_at' 
  end
end
Run Code Online (Sandbox Code Playgroud)


Pat*_*ify 25

这可以通过编写ActiveRecord :: Timestamp模块方法来完成.实际上并没有覆盖整个模块.我需要在使用遗留数据库时实现同样的目标.我在轨道3上,我已经开始遵循一种方法,如何通过编写rails功能来修补我的代码.

我首先创建我正在使用的基础项目,并在初始化程序中创建一个名为this的文件.在这种情况下,我创建了active_record.rb.在文件中我放置代码来覆盖控制时间戳的两个方法.以下是我的代码示例:

module ActiveRecord
    module Timestamp      
      private
      def timestamp_attributes_for_update #:nodoc:
        ["updated_at", "updated_on", "modified_at"]
      end
      def timestamp_attributes_for_create #:nodoc:
        ["created_at", "created_on"]
      end      
    end
  end
Run Code Online (Sandbox Code Playgroud)

注意:我还想提一下,这种用于让事情发挥作用的猴子补丁是不受欢迎的,并且可能会在升级时中断,所以要小心并充分意识到你想要做什么.

更新:

  • 将时间戳列名称从符号更改为字符串每个api更改.感谢Techbrunch将此API更改引起我的注意.


coo*_*sse 7

Rails >= 5.1更新 anwser。我建议ApplicationRecord在您的应用程序中使用默认可用的并定义以下内容:

class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  class << self
    private

    def timestamp_attributes_for_create
      super << 'my_created_at_column'
    end

    def timestamp_attributes_for_update
      super << 'my_updated_at_column'
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

请注意,如果您不想为所有模型配置它,您也可以在特定模型上使用此模块。

请注意,您应该使用字符串而不是符号。

  • 不知道为什么这埋得这么低。这是 Rails 5.1+ 的真正答案。谢谢! (3认同)

Bla*_*ten 6

您可以使用beforesave和beforecreate方法将DateTime.now发布到指定的列.

class Sample < ActiveRecord::Base
  before_create :set_time_stamps
  before_save :set_time_stamps

  private
  def set_time_stamps
    self.created_column = DateTime.now if self.new_record?
    self.updated_column = DateTime.now
  end
end
Run Code Online (Sandbox Code Playgroud)


Mil*_*ota 2

没有简单的方法可以做到这一点。您可以通过重写 ActiveRecord::Timestamp 模块或编写您自己的模块来实现这一目的。

这就是魔法的运作原理。

  • 仅供参考,上面的链接适用于旧版本的 Rails(2?)。如果您使用的是 Rails 3,请参阅 NPatel 的答案。 (2认同)