This project is archived and is in readonly mode.
named_scope fails when accessed through a class method over an association
Reported by unders | February 9th, 2009 @ 03:19 PM | in 2.x
When accessing a class method, that calls a named scope, through an association collection, the association scope seems to be lost.
Given
Layer
has_many :items
Item
named_scope :published, lambda { {:conditions => ['items.published_at < ?', Time.now.utc] } }
def.self find_v1
all
end
def.self find_v2
published
end
end
From the console:
> l = Layer.find :first
> l.items.find_v1
SELECT * FROM "items" WHERE ("items".layer_id = 1)
> l.items.find_v2
SELECT * FROM "items" WHERE (items.published_at < '2009-02-09 15:03:18')
This is where it goes wrong ("items".layer_id = 1)
is missing!
> l.items.published
SELECT * FROM "items" WHERE ("items".layer_id = 1) AND (items.published_at < '2009-02-09 15:06:37')
Accessing the named scope directly works perfectly fine
Versions: Rails 2.3.0 (same issue in 2.2.2) ruby 1.8.6 (2008-03-03 patchlevel 114) [universal-darwin9.0] sqlite3 -version 3.6.10
Comments and changes to this ticket
-
Daniel Guettler February 26th, 2009 @ 05:46 AM
Looks like the scoped_methods get popped before the query is actually executed. The call graph for l.items.find_v2 and l.items.published is actually quite different and I couldn't get my head around it to figure out how to fix this the right way. However applying this change to the named_scope.rb file fixes the issue and doesn't brake any existing tests in rails version 2.2.2. I don't consider this at proper patch just as a temp fix in case someone needs it.
--- a/activerecord/lib/active_record/named_scope.rb +++ b/activerecord/lib/active_record/named_scope.rb @@ -114,6 +114,7 @@ module ActiveRecord [options[:extend]].flatten.each { |extension| extend extension } if options[:extend] extend Module.new(&block) if block_given? @proxy_scope, @proxy_options = proxy_scope, options.except(:extend) + @scoped_methods = proxy_scope.send(:scoped_methods).dup end def reload @@ -166,9 +167,11 @@ module ActiveRecord if scopes.include?(method) scopes[method].call(self, *args) else - with_scope :find => proxy_options, :create => proxy_options[:conditions].is_a?(Hash) ? proxy_options[:conditions] : {} do - method = :new if method == :build - proxy_scope.send(method, *args, &block) + with_scope(@scoped_methods.last || {}) do + with_scope :find => proxy_options, :create => proxy_options[:conditions].is_a?(Hash) ? proxy_options[:conditions] : {} do + method = :new if method == :build + proxy_scope.send(method, *args, &block) + end end end end
-
Daniel Guettler February 26th, 2009 @ 05:58 AM
Ah actually this bug is already resolved in couple other tickets. E.g. #1960
-
CancelProfileIsBroken August 5th, 2009 @ 02:11 PM
- State changed from new to duplicate
Resolved by #1960
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>