This project is archived and is in readonly mode.
On-the-fly created named-scope raises 'undefined method `call' when called from subclass with cache_classes = true
Reported by Stephan Kaag | January 21st, 2010 @ 04:42 PM | in 2.3.10
Summary:
I create a named_scope at runtime (a pattern that searchlogic (http://github.com/binarylogic/searchlogic) also relies on). When the named-scope is first called on the super class an error is raised when I call that same scope in the subclass. I am not familiar enough with the codebase to provide a solution myself.
This error occurs in both Rails 2.3.5 and 3.0pre.
To reproduce:
Rails3::Application.configure do
config.cache_classes = true
end
class Candidate < ActiveRecord::Base
def self.create_second_order_scope
return if respond_to?(:second_order)
named_scope :second_order, :conditions => {}
end
end
class Admin::Candidate < Candidate
end
Error trigger:
Candidate.create_second_order_scope
Candidate.second_order
Admin::Candidate.create_second_order_scope
Admin::Candidate.second_order
>> undefined method `call' for nil:NilClass
Comments and changes to this ticket
-
Matt Jones February 4th, 2010 @ 09:27 PM
- Assigned user set to Matt Jones
I've experienced this EXACT problem, in the Hobo project which does automatic scope generation much like this.
See this ticket for more info, and the commit at the end of the ticket for a tweak that may help your case. As you can see in the ticket, I was supposed to have already made a ticket for this here... :)
If it works for you, I'll see about writing up a patch + some tests (you're welcome to give it a try as well).
-
Santiago Pastorino June 24th, 2010 @ 10:22 PM
- Milestone cleared.
- State changed from new to open
Can someone create a test case following https://rails.lighthouseapp.com/projects/8994/sending-patches
Thanks. -
Neeraj Singh June 25th, 2010 @ 01:44 AM
I am not able to reproduce this problem with rails3 edge.
ActiveRecord::Schema.define(:version => 20100624220122) do create_table "users", :force => true do |t| t.string "name" t.datetime "created_at" t.datetime "updated_at" end end class User < ActiveRecord::Base def self.create_second_order_scope return if respond_to?(:second_order) named_scope :second_order, :conditions => {} end def self.lab User.create_second_order_scope puts User.second_order.all.inspect end end class Admin::User < User def self.lab Admin::User.create_second_order_scope puts Admin::User.second_order.all.inspect end end # User.lab #=> produces sql query # Admin::User.lab #=> produces sql query
-
Santiago Pastorino June 25th, 2010 @ 02:56 AM
Neeraj did you do config.cache_classes = true? What about 2-3-stable?
-
Neeraj Singh June 25th, 2010 @ 03:54 AM
@Santiago I just did User.lab and Admin::User.lab in production environment and I get the same result.
will try with 2-3 and will let you know.
-
Matt Jones June 25th, 2010 @ 04:04 AM
@Neeraj: at least in Rails 2.3.x, the issue is caused by the scope's method being propagated up the inheritance chain, while the scope conditions are not. The trick is that the scopes are stored in an inheritable attribute - not a big deal for 3.0, since the methods are defined in-place without an actual reference to the array (see around line 89 in named_scopes.rb on master). On 2.3.x, the method that's defined only references the array:
define_method name do |*args| scopes[name].call(self, *args) end
Thus, in Admin::User above, you end up with a
second_order
method inherited from the parent, but scopes[:second_order] returns nil since the subclass has an empty hash which was inherited from the parent at definition time. -
Neeraj Singh June 25th, 2010 @ 10:10 PM
I can confirm that it is indeed and error with 2-3-stable. But it works fine on rails3 edge.
-
Neeraj Singh June 25th, 2010 @ 10:10 PM
- Tag changed from 2.3.5, 3.0pre, named_scope to 2.3.5, named_scope
-
Santiago Pastorino June 25th, 2010 @ 10:13 PM
- Milestone set to 2.3.9
- Tag changed from 2.3.5, named_scope to named_scope
-
Jeremy Kemper August 30th, 2010 @ 02:28 AM
- Milestone changed from 2.3.9 to 2.3.10
- Importance changed from to Low
-
mrcsparker October 18th, 2010 @ 11:36 PM
I put together some code based on the Hobo link placed here. I am still testing it, but it seems to work so far. Once I am sure that it works, I will put together the patch.
Here is the change to lib/active_record/named_scope.rb against 2.3.10
def named_scope(name, options = {}, &block)
name = name.to_sym scopes[name] = lambda do |parent_scope, *args| Scope.new(parent_scope, case options when Hash options when Proc if self.model_name != parent_scope.model_name options.bind(parent_scope).call(*args) else options.call(*args) end end, &block) end singleton_class.send :define_method, name do |*args| scopes[name].call(self, *args) end _name = name.to_sym _scope = scopes[_name] subclasses.each do |s| s.scopes[_name] = _scope end end end
-
Santiago Pastorino February 2nd, 2011 @ 04:29 PM
This issue has been automatically marked as stale because it has not been commented on for at least three months.
The resources of the Rails core team are limited, and so we are asking for your help. If you can still reproduce this error on the 3-0-stable branch or on master, please reply with all of the information you have about it and add "[state:open]" to your comment. This will reopen the ticket for review. Likewise, if you feel that this is a very important feature for Rails to include, please reply with your explanation so we can consider it.
Thank you for all your contributions, and we hope you will understand this step to focus our efforts where they are most helpful.
-
Santiago Pastorino February 2nd, 2011 @ 04:29 PM
- State changed from open to stale
-
Ryan Burrows February 14th, 2011 @ 09:08 PM
I just ran into this today on Rails 2.3.10 uses searchlogic.
I've attached a patch with a test that exposes the bug on Rails 2.3 stable and a fix for the issue. The fix is basically mrcsparker's fix above.
-
Ryan Burrows February 14th, 2011 @ 09:23 PM
- State changed from stale to open
Forgot to open the ticket
[state:open]
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>