mirror of
https://github.com/github/rails.git
synced 2026-04-26 03:00:59 -04:00
Make relations work as scopes
This commit is contained in:
@@ -106,7 +106,7 @@ module ActiveRecord
|
||||
|
||||
scopes[name] = lambda do |parent_scope, *args|
|
||||
Scope.new(parent_scope, case options
|
||||
when Hash
|
||||
when Hash, Relation
|
||||
options
|
||||
when Proc
|
||||
options.call(*args)
|
||||
@@ -132,13 +132,21 @@ module ActiveRecord
|
||||
delegate :scopes, :with_scope, :scoped_methods, :unscoped, :to => :proxy_scope
|
||||
|
||||
def initialize(proxy_scope, options, &block)
|
||||
options ||= {}
|
||||
[options[:extend]].flatten.each { |extension| extend extension } if options[:extend]
|
||||
extend Module.new(&block) if block_given?
|
||||
|
||||
options ||= {}
|
||||
if options.is_a?(Hash)
|
||||
Array.wrap(options[:extend]).each {|extension| extend extension }
|
||||
@proxy_options = options.except(:extend)
|
||||
else
|
||||
@proxy_options = options
|
||||
end
|
||||
|
||||
unless Scope === proxy_scope
|
||||
@current_scoped_methods_when_defined = proxy_scope.send(:current_scoped_methods)
|
||||
end
|
||||
@proxy_scope, @proxy_options = proxy_scope, options.except(:extend)
|
||||
|
||||
@proxy_scope = proxy_scope
|
||||
end
|
||||
|
||||
def reload
|
||||
@@ -193,7 +201,13 @@ module ActiveRecord
|
||||
protected
|
||||
|
||||
def relation
|
||||
@relation ||= unscoped.apply_finder_options(proxy_options)
|
||||
@relation ||= begin
|
||||
if proxy_options.is_a?(Hash)
|
||||
unscoped.apply_finder_options(proxy_options)
|
||||
else
|
||||
unscoped.merge(proxy_options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def proxy_found
|
||||
@@ -201,6 +215,7 @@ module ActiveRecord
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def method_missing(method, *args, &block)
|
||||
if scopes.include?(method)
|
||||
scopes[method].call(self, *args)
|
||||
@@ -221,6 +236,7 @@ module ActiveRecord
|
||||
def load_found
|
||||
@found = find(:all)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -19,7 +19,10 @@ module ActiveRecord
|
||||
raise ArgumentError, "Cannot merge a #{r.klass.name}(##{r.klass.object_id}) relation with #{@klass.name}(##{@klass.object_id}) relation"
|
||||
end
|
||||
|
||||
merged_relation = spawn.eager_load(r.eager_load_values).preload(r.preload_values).includes(r.includes_values)
|
||||
merged_relation = spawn
|
||||
return merged_relation unless r
|
||||
|
||||
merged_relation = merged_relation.eager_load(r.eager_load_values).preload(r.preload_values).includes(r.includes_values)
|
||||
|
||||
merged_relation.readonly_value = r.readonly_value unless r.readonly_value.nil?
|
||||
merged_relation.limit_value = r.limit_value if r.limit_value.present?
|
||||
@@ -94,9 +97,10 @@ module ActiveRecord
|
||||
:order, :select, :readonly, :group, :having, :from, :lock ]
|
||||
|
||||
def apply_finder_options(options)
|
||||
options.assert_valid_keys(VALID_FIND_OPTIONS)
|
||||
|
||||
relation = spawn
|
||||
return relation unless options
|
||||
|
||||
options.assert_valid_keys(VALID_FIND_OPTIONS)
|
||||
|
||||
relation = relation.joins(options[:joins]).
|
||||
where(options[:conditions]).
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class Post < ActiveRecord::Base
|
||||
named_scope :containing_the_letter_a, :conditions => "body LIKE '%a%'"
|
||||
named_scope :ranked_by_comments, :order => "comments_count DESC"
|
||||
named_scope :limit_by, lambda {|limit| {:limit => limit} }
|
||||
named_scope :containing_the_letter_a, where("body LIKE '%a%'")
|
||||
named_scope :ranked_by_comments, order("comments_count DESC")
|
||||
named_scope :limit_by, lambda {|l| limit(l) }
|
||||
named_scope :with_authors_at_address, lambda { |address| {
|
||||
:conditions => [ 'authors.author_address_id = ?', address.id ],
|
||||
:joins => 'JOIN authors ON authors.id = posts.author_id'
|
||||
@@ -20,7 +20,7 @@ class Post < ActiveRecord::Base
|
||||
has_one :last_comment, :class_name => 'Comment', :order => 'id desc'
|
||||
|
||||
named_scope :with_special_comments, :joins => :comments, :conditions => {:comments => {:type => 'SpecialComment'} }
|
||||
named_scope :with_very_special_comments, :joins => :comments, :conditions => {:comments => {:type => 'VerySpecialComment'} }
|
||||
named_scope :with_very_special_comments, joins(:comments).where(:comments => {:type => 'VerySpecialComment'})
|
||||
named_scope :with_post, lambda {|post_id|
|
||||
{ :joins => :comments, :conditions => {:comments => {:post_id => post_id} } }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user