module ActiveRecord
  module ActsAsRelation
    module AccessMethods
      protected
      def define_acts_as_accessor(attrib, model_name)
        class_eval do
          define_method attrib do
            send(model_name).send(attrib)
          end

          define_method "#{attrib}=" do |value|
            send(model_name).send("#{attrib}=", value)
          end

          define_method "#{attrib}?" do
            send(model_name).send("#{attrib}?")
          end
        end
      end

      def define_acts_as_accessors(attribs, model_name)
        attribs.each do |attrib|
          define_acts_as_accessor(attrib, model_name)
        end
      end
    end
  end
end

module ActiveRecord
  module ActsAsRelation
    module AccessMethods
      protected
      def define_acts_as_accessors(attribs, model_name)
        # The weird order of the if-else branches is so that we query ourselves
        # before we query our superclass.
        class_eval <<-EndCode, __FILE__, __LINE__ + 1
          def method_missing(method, *args, &proc)
            if #{model_name}.respond_to?(method)
              self.class_eval do
                delegate method, to: :#{model_name}
              end
              #{model_name}.send(method, *args, &proc)
            else
              super
            end
          end

          def read_attribute(attr_name, *args, &proc)
            if attribute_method?(attr_name.to_s)
              super(attr_name, *args)
            else
              #{model_name}.read_attribute(attr_name, *args, &proc)
            end
          end

          private

          def write_attribute(attr_name, *args, &proc)
            if attribute_method?(attr_name.to_s)
              super(attr_name, *args)
            else
              #{model_name}.send(:write_attribute, attr_name, *args, &proc)
            end
          end
        EndCode
      end
    end
  end
end

Implement lazy delegation of properties from the child to the super class.
Implement lazy delegation of properties from the child to the super class.

This has better support for timestamping since we use the lower-level *_attribute methods.
