We have a stand-alone ActiveRecord CLI application which has a magic column shim or monkey-patch to the AR create and update methods. This worked with AR-3 and AR-4.0 but fails with AR-4.1. This failure is apparently related to AR4.1 using autoload for its persistence library and thus the necessary methods are not available in ActiveRecord::Base to override during initialisation.
I am not sure how to fix this and am looking for suggestions on what is the best approach for 4.1. It would be nice to have a solution that could backport to 4.0 as well but one that works just for 4.1 is good enough.
Basically our patch uses the alias_method_chain to intercept a call to either create or update methods. It then checks for the existance of one or more columns from a list. For each one found it calls a specific update method, writes the attribute and returns. The technique we used is similar to ARs default magic columns as implemented in the rails/timestamps module in Rails3. In AR 3 and 4.0 the module was included in this fashion:
module HLLAuditStamps . . . public def self.included( base ) # create/update became create_record/update_record in Rails-4.0 base.alias_method_chain( :create_record, :audit ) base.alias_method_chain( :update_record, :audit ) # for AR-3.2 use this instead #base.alias_method_chain( :create, :audit ) #base.alias_method_chain( :update, :audit ) end end class ActiveRecord::Base require( 'active_record/persistence' ) include HLLAuditStamps end
This was loaded using an initialiser with a full RoR stack or in the first call to AR in our CLI appliction. There has to be a way to make this work since AR still supports timestamps. However, the code has substancially changed from that similar to the above:
module ActiveRecord # Active Record automatically timestamps create and update operations if the table has fields # named created_at/created_on or updated_at/updated_on. # # Timestamping can be turned off by setting # <tt>ActiveRecord::Base.record_timestamps = false</tt> # # Timestamps are in the local timezone by default but you can use UTC by setting # <tt>ActiveRecord::Base.default_timezone = :utc</tt> module Timestamp def self.included(base) #:nodoc: base.alias_method_chain :create, :timestamps base.alias_method_chain :update, :timestamps base.class_inheritable_accessor :record_timestamps, :instance_writer => false base.record_timestamps = true end private . . .
module Timestamp extend ActiveSupport::Concern included do class_attribute :record_timestamps self.record_timestamps = true end def initialize_dup(other) # :nodoc: super clear_timestamp_attributes end private
What I need is some lucid explaination as to how the second form of implementation works in AR-4.1 and how one inserts ones own 'magic' columns into AR updates given the move to lazy library loading via autoload. I have taken a look at UserStamp (https://github.com/d...tamp/stamper.rb) but they seem to use a similar technique to what I am doings - although they also seem to actually open ARs internal modules and have also run into a major problem with 4.1 compatiblity (https://github.com/delynn/userstamp/issues/24).
Suggestions anyone? Does AR-4 provide a 'hook' to add ones own magic columns and their dependent processing?