Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Association extensions and scopes on the associated model behave inconsistantly

#1221

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.

Reported by Brian Terlson · October 15th, 2008 @ 09:27 PM

State: resolved
Milestone: 2.x
Assigned to: Frederick Cheung Frederick Cheung
Importance: none

Activity

  1. Brian Terlson
    Brian Terlson

    I cannot recreate this behavior in 2.2.0 RC, so I'd say this ticket can be closed.

    October 30th, 2008 @ 10:25 PM

  2. Frederick Cheung
    Frederick Cheung
    • State changed from new to resolved

    December 13th, 2008 @ 04:22 PM

  3. Mani Tadayon
    Mani Tadayon
    • 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.

    August 19th, 2010 @ 09:03 PM

  4. Mani Tadayon
    Mani Tadayon

    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_extensions

    Also, 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
        }
    ]
    

    August 19th, 2010 @ 09:15 PM

  5. Harm Aarts
    Harm Aarts
    • 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

    September 10th, 2010 @ 12:53 PM