This project is archived and is in readonly mode.

#424 ✓invalid
Dennis Krupenik

named_scope does not respect eager loading

Reported by Dennis Krupenik | June 16th, 2008 @ 09:24 PM


class Person
  has_many :messages
end

class Message
  belongs_to :person
  named_scope :unread, :conditions => { :is_read => false }
end

@person = Person.first(:include => :messages) # performs an sql query
@person.messages.unread # performs another sql query. should it?
@person.messages.find_all { |msg| !msg.is_read } # does not perform sql query.
@person.messages.unread.find_all { true } # completely ignores '.unread'. should it?

i'm not sure whether it is a bug or a feature.

is there a way to utilize existing named_scopes to perform filtering on already loaded associations without additional queries?

Comments and changes to this ticket

  • elDub

    elDub July 17th, 2008 @ 03:24 PM

    • Tag set to eager_loading, named_scope

    I have been battling with this issue as well. I think the problem is more related to 'has_one' relationships though.

    class Document < ActiveRecord::Base
      has_one :revision, :class_name => 'Document', :foreign_key => 'prior_revision_id'
      belongs_to :prior_revision, :class_name => 'Document', :foreign_key => 'prior_revision_id'
      
      named_scope :active, :conditions => { :active => true }
      named_scope :inactive, :conditions => { :active => false }
    end
    

    And then in script/console:

    Loading development environment (Rails 2.1.0)
    >> d1 = Document.create(:active => false, :title => 'd1', :body => 'text')
    => #<Document id: 1, prior_revision_id: nil, title: "d1", body: "text", active: false, created_at: "2008-07-17 14:18:36", updated_at: "2008-07-17 14:18:36">
    >> d2 = d1.create_revision(:active => true, :title => 'd2', :body => 'new text')
    => #<Document id: 2, prior_revision_id: 1, title: "d2", body: "new text", active: true, created_at: "2008-07-17 14:19:14", updated_at: "2008-07-17 14:19:14">
    
    >> doc = Document.find(1, :include => :revision)
    => #<Document id: 1, prior_revision_id: nil, title: "d1", body: "text", active: false, created_at: "2008-07-17 14:18:36", updated_at: "2008-07-17 14:18:36">
    >> doc.revision
    => #<Document id: 2, prior_revision_id: 1, title: "d2", body: "new text", active: true, created_at: "2008-07-17 14:19:14", updated_at: "2008-07-17 14:19:14">
    
    >> ns_doc = Document.inactive.find(:all, :include => :revision)[0]
    => #<Document id: 1, prior_revision_id: nil, title: "d1", body: "text", active: false, created_at: "2008-07-17 14:18:36", updated_at: "2008-07-17 14:18:36">
    >> ns_doc.revision
    => nil
    

    Note how the attempt to use eager loading within a named scope request causes the same document (id: 1) to NOT be able to access it's revision.

  • elDub

    elDub July 17th, 2008 @ 03:37 PM

    Please forgive/ignore my prior post. After re-thinking it, it is a different issue which I will create a new post for.

  • Tarmo Tänav

    Tarmo Tänav September 18th, 2008 @ 06:51 AM

    • State changed from “new” to “invalid”
    • Tag changed from eager_loading, named_scope to eager_loading, named_scope

    Since conditions on named_scope's can be arbitrarily complex SQL snippets it is impossible to filter the association by the named scope in AR alone, making an exception for simple hash based conditions does not seem likely to happen.

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>

People watching this ticket

Pages