lib/active_record/acts_as/instance_methods.rb
module ActiveRecord
module ActsAs
module InstanceMethods
def acting_as?(other = nil)
self.class.acting_as? other
end
def is_a?(klass)
super || acting_as?(klass)
end
def changed?
super || acting_as.changed? || @_acting_as_changed
end
def acting_as_foreign_key
acting_as[acting_as_reflection.foreign_key]
end
# Is the superclass persisted to the database?
def acting_as_persisted?
return false if acting_as.nil?
!acting_as.id.nil? && !acting_as_foreign_key.nil?
end
def actable_must_be_valid
if validates_actable
unless acting_as.valid?
acting_as.errors.each do |att, message|
errors.add(att, message)
end
end
end
end
protected :actable_must_be_valid
def read_attribute(attr_name, *args, &block)
if attribute_method?(attr_name.to_s)
super
else
acting_as.read_attribute(attr_name, *args, &block)
end
end
def write_attribute(attr_name, value, *args, &block)
if attribute_method?(attr_name.to_s)
super
else
acting_as.send(:write_attribute, attr_name, value, *args, &block)
end
end
def read_store_attribute(store_attribute, key)
if attribute_method?(store_attribute.to_s)
super
else
acting_as.read_store_attribute(store_attribute, key)
end
end
def write_store_attribute(store_attribute, key, value)
if attribute_method?(store_attribute.to_s)
super
else
acting_as.send(:write_store_attribute, store_attribute, key, value)
end
end
private :write_attribute, :write_store_attribute
def attributes
acting_as.nil? ? super : acting_as.attributes.except(acting_as_reflection.type, acting_as_reflection.foreign_key).merge(super)
end
def attribute_names
acting_as.nil? ? super : super | (acting_as.attribute_names - [acting_as_reflection.type, acting_as_reflection.foreign_key])
end
def has_attribute?(attr_name, as_original_class = false)
if as_original_class
super(attr_name)
else
super(attr_name) || acting_as.has_attribute?(attr_name)
end
end
def column_for_attribute(name)
if has_attribute?(name, true)
super(name)
else
acting_as.column_for_attribute(name)
end
end
def touch(*args)
acting_as.touch(*args) if acting_as.persisted?
end
def respond_to?(name, include_private = false, as_original_class = false)
as_original_class ? super(name, include_private) : super(name, include_private) || acting_as.respond_to?(name)
end
def self_respond_to?(name, include_private = false)
respond_to? name, include_private, true
end
def dup
duplicate = super
duplicate.acting_as = acting_as.dup
duplicate
end
def method_missing(method, *args, &block)
uses_superclass_for?(method) ? acting_as.send(method, *args, &block) : super
end
def uses_superclass_for?(method)
responds_locally = self_respond_to?(method)
if acting_as.respond_to?(method)
if responds_locally
false
else
# Only use getters if the superclass has
# an instance that is linked to this class instance.
if acting_as_persisted?
true
else
responds_locally ? false : true
end
end
else
# If the superclass doesn't have it, use this class's methods
false
end
end
end
end
end