Skip to content

Instantly share code, notes, and snippets.

@fullsailor
Created July 5, 2012 21:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fullsailor/3056392 to your computer and use it in GitHub Desktop.
Save fullsailor/3056392 to your computer and use it in GitHub Desktop.
Polymorphic #where method in ActiveRecord
class Activity < ActiveRecord::Base
belongs_to :actor, polymorphic: true
belongs_to :thing, polymorphic: true
belongs_to :target, polymorphic: true
def self.polywhere(opts)
t = arel_table
ands = opts.map do |assoc, obj|
left_eq = t["#{assoc}_id"].eq(obj.id)
right_eq = t["#{assoc}_type"].eq(obj.class.model_name)
and_node = Arel::Nodes::And.new([left_eq, right_eq])
Arel::Nodes::Grouping.new(and_node)
end
ors = ands.reduce do |memo, and_node|
if memo
Arel::Nodes::Or.new(and_node, memo)
else
and_node
end
end
where(ors)
end
end
p = Property.first
Activity.polywhere(actor: p, thing: p, target: p)
SELECT "activities".* FROM "activities" WHERE (("activities"."actor_id" = 1 AND "activities"."actor_type" = 'Property') OR ("activities"."target_id" = 1 AND "activities"."target_type" = 'Property') OR ("activities"."thing_id" = 1 AND "activities"."thing_type" = 'Property'))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment