This project is archived and is in readonly mode.
Association extensions and scopes on the associated model behave inconsistantly
Reported by Brian Terlson | October 15th, 2008 @ 09:27 PM | in 2.x
I'm noticing some undesirable behavior with named scopes and association extensions with Rails 2.1.1. Observe the following contrived example:
class Blog < ActiveRecord::Base
has_many :entries do
def print
each { |e| puts e }
end
end
end
class Entry < ActiveRecord::Base
belongs_to :blog
named_scope :active, :conditions => {:status => 'active'}
named_scope :inactive, :conditions => {:status => 'inactive'}
end
Now, moving to the console...
>> b = Blog.first
=> #<Blog id: 1, created_at: "2008-10-15 19:52:40", updated_at: "2008-10-15 19:52:40">
>> b.entries
=> [#<Entry id: 1, blog_id: 1, status: "active", created_at: "2008-10-15 19:52:54", updated_at: "2008-10-15 19:52:54">, #<Entry id: 2, blog_id: 1, status: "active", created_at: "2008-10-15 19:52:58", updated_at: "2008-10-15 19:52:58">, #<Entry id: 3, blog_id: 1, status: "inactive", created_at: "2008-10-15 19:53:01", updated_at: "2008-10-15 19:53:01">]
3 entries are made, 2 active, 1 inactive.
>> reload!
Reloading...
>> b.entries.print
#<Entry:0x33482b4>
#<Entry:0x334729c>
#<Entry:0x334724c>
=> [#<Entry id: 1, blog_id: 1, status: "active", created_at: "2008-10-15 19:52:54", updated_at: "2008-10-15 19:52:54">, #<Entry id: 2, blog_id: 1, status: "active", created_at: "2008-10-15 19:52:58", updated_at: "2008-10-15 19:52:58">, #<Entry id: 3, blog_id: 1, status: "inactive", created_at: "2008-10-15 19:53:01", updated_at: "2008-10-15 19:53:01">]
>> b.entries.inactive.print
#<Entry:0x33482b4>
#<Entry:0x334729c>
#<Entry:0x334724c>
=> [#<Entry id: 1, blog_id: 1, status: "active", created_at: "2008-10-15 19:52:54", updated_at: "2008-10-15 19:52:54">, #<Entry id: 2, blog_id: 1, status: "active", created_at: "2008-10-15 19:52:58", updated_at: "2008-10-15 19:52:58">, #<Entry id: 3, blog_id: 1, status: "inactive", created_at: "2008-10-15 19:53:01", updated_at: "2008-10-15 19:53:01">]
After calling entries.print, subsequent scopes are ignored when calling the print method. Expected behavior can be achieved by calling the desired scope first, although all subsequent scopes will not be correct...
>> reload!
Reloading...
=> true
>> b = Blog.first
=> #<Blog id: 1, created_at: "2008-10-15 19:52:40", updated_at: "2008-10-15 19:52:40">
>> b.entries.inactive
=> [#<Entry id: 3, blog_id: 1, status: "inactive", created_at: "2008-10-15 19:53:01", updated_at: "2008-10-15 19:53:01">]
>> b.entries.inactive.print
#<Entry:0x32eed54>
=> [#<Entry id: 3, blog_id: 1, status: "inactive", created_at: "2008-10-15 19:53:01", updated_at: "2008-10-15 19:53:01">]
>> b.entries.print
#<Entry:0x32eed54>
=> [#<Entry id: 3, blog_id: 1, status: "inactive", created_at: "2008-10-15 19:53:01", updated_at: "2008-10-15 19:53:01">]
It should be noted that scopes do behave correctly when not calling the print method.
>> b.entries.inactive.print
#<Entry:0x32218e0>
#<Entry:0x3221570>
#<Entry:0x32213f4>
=> [#<Entry id: 1, blog_id: 1, status: "active", created_at: "2008-10-15 19:52:54", updated_at: "2008-10-15 19:52:54">, #<Entry id: 2, blog_id: 1, status: "active", created_at: "2008-10-15 19:52:58", updated_at: "2008-10-15 19:52:58">, #<Entry id: 3, blog_id: 1, status: "inactive", created_at: "2008-10-15 19:53:01", updated_at: "2008-10-15 19:53:01">]
>> b.entries.inactive
=> [#<Entry id: 3, blog_id: 1, status: "inactive", created_at: "2008-10-15 19:53:01", updated_at: "2008-10-15 19:53:01">]
This behavior seems pretty buggy -- at the very least, inconsistent.
Comments and changes to this ticket
-
Brian Terlson October 30th, 2008 @ 10:25 PM
I cannot recreate this behavior in 2.2.0 RC, so I'd say this ticket can be closed.
-
Frederick Cheung December 13th, 2008 @ 04:22 PM
- State changed from new to resolved
-
Mani Tadayon August 19th, 2010 @ 09:03 PM
- Importance changed from to
I am encountering this exact same bug on Rails 2.3.8!
I created a blank new rails app using the example code above, with one tiny change to the Blog class to help with debugging:
class Blog < ActiveRecord::Base has_many :entries do def print each { |e| puts e.status } # print the status end end end
Here is what happens in the console:
>> Rails.version "2.3.8" >> b = Blog.first #<Blog:0x2397edc> { :id => 1, :created_at => Thu, 19 Aug 2010 19:36:44 UTC +00:00, :updated_at => Thu, 19 Aug 2010 19:36:44 UTC +00:00 } >> b.entries [ [0] #<Entry:0x23767b4> { :id => 1, :status => "active", :blog_id => 1, :created_at => Thu, 19 Aug 2010 19:37:02 UTC +00:00, :updated_at => Thu, 19 Aug 2010 19:37:02 UTC +00:00 }, [1] #<Entry:0x2376750> { :id => 2, :status => "active", :blog_id => 1, :created_at => Thu, 19 Aug 2010 19:37:04 UTC +00:00, :updated_at => Thu, 19 Aug 2010 19:37:04 UTC +00:00 }, [2] #<Entry:0x2376700> { :id => 3, :status => "inactive", :blog_id => 1, :created_at => Thu, 19 Aug 2010 19:37:06 UTC +00:00, :updated_at => Thu, 19 Aug 2010 19:37:06 UTC +00:00 } ] >> b.entries.active.print active active inactive # this shouldn't be here! nil >> Blog.first.entries.active.print active active nil >> Blog.first.entries.inactive.print inactive nil
Notice that the problem only occurs when an instance is stored in a variable. Going through the model using Blog.first yields the expected results. I am not familiar with how ActiveRecord handles association extensions internally, but it appears like some kind of caching is to blame for this.
-
Mani Tadayon August 19th, 2010 @ 09:15 PM
I created a github repo with a test app in case anyone wants to see if they can recreate this:
http://github.com/bowsersenior/test_association_extensionsAlso, here is one more example that shows how c.entries is totally fouled up after calling c.entries.inactive.print:
>> c = Blog.first #<Blog:0x237af58> { :id => 1, :created_at => Thu, 19 Aug 2010 19:36:44 UTC +00:00, :updated_at => Thu, 19 Aug 2010 19:36:44 UTC +00:00 } >> c.entries.inactive [ [0] #<Entry:0x2374a54> { :id => 3, :status => "inactive", :blog_id => 1, :created_at => Thu, 19 Aug 2010 19:37:06 UTC +00:00, :updated_at => Thu, 19 Aug 2010 19:37:06 UTC +00:00 } ] >> c.entries.inactive.print inactive nil >> c.entries.print inactive nil >> c.entries [ [0] #<Entry:0x236ccdc> { :id => 3, :status => "inactive", :blog_id => 1, :created_at => Thu, 19 Aug 2010 19:37:06 UTC +00:00, :updated_at => Thu, 19 Aug 2010 19:37:06 UTC +00:00 } ] >> Blog.first.entries [ [0] #<Entry:0x2363f10> { :id => 1, :status => "active", :blog_id => 1, :created_at => Thu, 19 Aug 2010 19:37:02 UTC +00:00, :updated_at => Thu, 19 Aug 2010 19:37:02 UTC +00:00 }, [1] #<Entry:0x2363ec0> { :id => 2, :status => "active", :blog_id => 1, :created_at => Thu, 19 Aug 2010 19:37:04 UTC +00:00, :updated_at => Thu, 19 Aug 2010 19:37:04 UTC +00:00 }, [2] #<Entry:0x2363e70> { :id => 3, :status => "inactive", :blog_id => 1, :created_at => Thu, 19 Aug 2010 19:37:06 UTC +00:00, :updated_at => Thu, 19 Aug 2010 19:37:06 UTC +00:00 } ]
-
Harm Aarts September 10th, 2010 @ 12:53 PM
- Assigned user set to Frederick Cheung
How is this "resolved"? IMHO this is still broken. Using Rails 2.3.8 and Ruby 1.9.1
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>