Renaming the created_at, updated_at columns of ActiveRecord/Rails

前端 未结 10 617
囚心锁ツ
囚心锁ツ 2020-11-28 07:02

I want to rename the timestamp columns defined in timestamp.rb . Can the methods of timestamp.rb be overwritten? And what has to be done in the application that the module w

相关标签:
10条回答
  • 2020-11-28 07:35

    The correct syntax for doing this in rails 4.2

    class User < ActiveRecord::Base
    ...
    
    private
    
        def timestamp_attributes_for_create
            super << 'date_add'
        end
    
        def timestamp_attributes_for_update
            super << 'date_update'
        end
    end
    
    0 讨论(0)
  • 2020-11-28 07:40

    This can be done via just over writing the ActiveRecord::Timestamp module methods. Not actually overwriting the entire module. I need to to accomplish this same goal as I am working with a legacy database. I am on rails 3 and I have started following a methodology of how to monkey patch my code with over writing rails functionality.

    I first create the base project that I am working with and create a file called that in the initializers. In this case I created active_record.rb. And within the file I put code to override two methods that controlled the timestamp. Below is the sample of my code:

    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
    

    NOTE: I would also like to mention that this sort of monkey patching to get things to work is frowned upon and may break on upgrades so be careful and be fully aware of what it is that you want to do.

    Updates:

    • Change timestamp column names from symbol to string per api change. Thanks Techbrunch for bringing this API change to my attention.
    0 讨论(0)
  • 2020-11-28 07:46

    I think NPatel's method is a right approach, but it is doing too much if you only need to change #created_at on a single model. Since the Timestamp module is included in every AR object, you can just override it per model, not globally.

    <= Rails 5.0

    class User < ActiveRecord::Base
      ...
      private
      def timestamp_attributes_for_create
        super << :registered_at
      end
    end
    

    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
    
    0 讨论(0)
  • 2020-11-28 07:47

    You could use the beforesave and beforecreate methods to post the DateTime.now to your specified columns.

    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
    
    0 讨论(0)
  • 2020-11-28 07:49

    An updated anwser for Rails >= 5.1. I would suggest to use the ApplicationRecord that is available by default in your application and define the following:

    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
    

    Note that you can also use this block on a specific model if you don't want to configure it for all your models.

    Note also that you should use strings and not symbols.

    0 讨论(0)
  • 2020-11-28 07:50

    quick ugly hack, elaborating from Milan Novota's answer: append the following to environment.rb, replacing the values of the CREATED_COL and UPDATED_COL constants with the desired column names:

    
    module ActiveRecord
      module Timestamp
        CREATED_COL = 'created_at'
        UPDATED_COL = 'updated_at'
        private
          def create_with_timestamps #:nodoc:
            if record_timestamps
              t = self.class.default_timezone == :utc ? Time.now.utc : Time.now
              write_attribute(CREATED_COL, t) if respond_to?(CREATED_COL) && send(CREATED_COL).nil?
              write_attribute(UPDATED_COL, t) if respond_to?(UPDATED_COL) && send(UPDATED_COL).nil?
            end
            create_without_timestamps
          end
    
          def update_with_timestamps(*args) #:nodoc:
            if record_timestamps && (!partial_updates? || changed?)
              t = self.class.default_timezone == :utc ? Time.now.utc : Time.now
              write_attribute(UPDATED_COL, t) if respond_to?(UPDATED_COL)
            end
            update_without_timestamps(*args)
          end
      end
    end
    
    0 讨论(0)
提交回复
热议问题