Skip to content

Instantly share code, notes, and snippets.

@armstrjare
Created March 26, 2011 21:37
Show Gist options
  • Save armstrjare/888662 to your computer and use it in GitHub Desktop.
Save armstrjare/888662 to your computer and use it in GitHub Desktop.
Defines a bunch of helper methods for polymorphic associations.
module PolymorphicEntity
module ActiveRecordExtension
# Defines a bunch of helper methods for polymorphic associations.
def has_polymorphic_entity(*associations)
associations.each do |assoc|
# def sender_entity
# self.sender_id ? "#{self.sender_type}##{self.sender_id}" : nil
# end
define_method("#{assoc}_entity") do
self.send("#{assoc}_id") ? "#{self.send("#{assoc}_type")}##{self.send("#{assoc}_id")}" : nil
end
# def sender_entity=(polymorphic_id)
# type, id = polymorphic_id.to_s.split("#")
# self.sender_type = type
# self.sender_id = id
# end
define_method("#{assoc}_entity=") do |polymorphic_id|
if polymorphic_id.present?
type, id = polymorphic_id.to_s.split("#")
self.send("#{assoc}_type=", type)
self.send("#{assoc}_id=", id)
self.send("#{assoc}").reload
else
self.send("#{assoc}=", nil)
end
end
# def sender_changed?
# sender_id_changed? || sender_type_changed?
# end
define_method("#{assoc}_changed?") do
send("#{assoc}_id_changed?") || send("#{assoc}_type_changed?")
end
# def sender_was
# (self.sender_type_was || self.sender_type).constantize.find(self.sender_id_was || self.sender_id)
# end
define_method("#{assoc}_was") do
type = send("#{assoc}_type_was") || send("#{assoc}_type")
id = send("#{assoc}_id_was") || send("#{assoc}_id")
type && id ? type.constantize.find_by_id(id) : nil
end
# Define some class helpers...
self.class.instance_eval do
# def where_sender_is(sender)
# where("#{table_name}.sender_id = ? and #{table_name}.sender_type = ?", sender.id, sender.class.base_class.name)
# end
define_method("where_#{assoc}_is") do |entity|
where("#{table_name}.#{assoc}_id = ? and #{table_name}.#{assoc}_type = ?", entity.id, entity.class.base_class.name)
end
# def where_sender_is_not(sender)
# where("#{table_name}.sender_id <> ? OR #{table_name}.sender_type <> ?", sender.id, sender.class.base_class.name)
# end
define_method("where_#{assoc}_is_not") do |entity|
where("#{table_name}.#{assoc}_id <> ? OR #{table_name}.#{assoc}_type <> ?", entity.id, entity.class.base_class.name)
end
end
end
end
end
ActiveRecord::Base.send(:extend, PolymorphicEntity::ActiveRecordExtension)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment