diff options
author | Jon Leighton <j@jonathanleighton.com> | 2012-08-03 10:50:49 +0100 |
---|---|---|
committer | Jon Leighton <j@jonathanleighton.com> | 2012-08-03 11:05:31 +0100 |
commit | bf2df6e7ba495ac4d2264e0e2558c366f217ee5d (patch) | |
tree | 775ae427819b2200b0ae3c85619d4f5cc8f8c203 /activerecord/lib/active_record | |
parent | c391919180a19a31a04b9483396d0543a4bed961 (diff) | |
download | rails-bf2df6e7ba495ac4d2264e0e2558c366f217ee5d.tar.gz rails-bf2df6e7ba495ac4d2264e0e2558c366f217ee5d.tar.bz2 rails-bf2df6e7ba495ac4d2264e0e2558c366f217ee5d.zip |
Allow Relation#merge to take a proc.
This was requested by DHH to allow creating of one's own custom
association macros.
For example:
module Commentable
def has_many_comments(extra)
has_many :comments, -> { where(:foo).merge(extra) }
end
end
class Post < ActiveRecord::Base
extend Commentable
has_many_comments -> { where(:bar) }
end
Diffstat (limited to 'activerecord/lib/active_record')
-rw-r--r-- | activerecord/lib/active_record/relation/spawn_methods.rb | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/activerecord/lib/active_record/relation/spawn_methods.rb b/activerecord/lib/active_record/relation/spawn_methods.rb index dcd4c78eb7..5394c1b28b 100644 --- a/activerecord/lib/active_record/relation/spawn_methods.rb +++ b/activerecord/lib/active_record/relation/spawn_methods.rb @@ -23,6 +23,13 @@ module ActiveRecord # # Returns the intersection of all published posts with the 5 most recently created posts. # # (This is just an example. You'd probably want to do this with a single query!) # + # Procs will be evaluated by merge: + # + # Post.where(published: true).merge(-> { joins(:comments) }) + # # => Post.where(published: true).joins(:comments) + # + # This is mainly intended for sharing common conditions between multiple associations. + # def merge(other) if other.is_a?(Array) to_a & other @@ -35,8 +42,12 @@ module ActiveRecord # Like #merge, but applies changes in place. def merge!(other) - klass = other.is_a?(Hash) ? Relation::HashMerger : Relation::Merger - klass.new(self, other).merge + if !other.is_a?(Relation) && other.respond_to?(:to_proc) + instance_exec(&other) + else + klass = other.is_a?(Hash) ? Relation::HashMerger : Relation::Merger + klass.new(self, other).merge + end end # Removes from the query the condition(s) specified in +skips+. |