This project is archived and is in readonly mode.

#3610 ✓invalid
Khurram Virani

has_many :through associations may not respect default_scope :conditions

Reported by Khurram Virani | December 23rd, 2009 @ 07:28 PM

class Book < ActiveRecord::Base
  has_many :chapters, :as => :content, :dependent => :destroy
  has_many :paragraphs, :through => :chapters
end

class Chapter < ActiveRecord::Base
  belongs_to :content, :polymorphic => true
  has_many :paragraphs
end

class Paragraph < ActiveRecord::Base
  default_scope :conditions => { :deleted_at => nil } # changing this to :conditions => ["paragraphs.deleted_at IS NULL"]
  belongs_to :chapter
end

Book.paragraphs.all # => ignores conditions and returns records with that have deleted_at set (not null)!

I kept the polymorphism in here because my production code has it. Not sure if it is related to the bug at all...I think it's happening because of using the conditions hash - the table name is being inferred incorrectly ... or something... going to investigate more shortly.

Looks like is_paranoid is resolving this by hacking the has_many method (but in a tightly coupled way that isn't really correct): http://github.com/semanticart/is_paranoid/commit/fae6f0d3b056f7ba29...

Comments and changes to this ticket

  • Khurram Virani

    Khurram Virani December 23rd, 2009 @ 07:29 PM

    comment should read:

    changing this to :conditions => ["paragraphs.deleted_at IS NULL"] may fix the issue

  • Mateo Murphy

    Mateo Murphy August 3rd, 2010 @ 03:57 AM

    Just ran into this issue using while using the "paranoid" gem. I don't think it's related to the conditions hash, since the paranoid gem uses the string syntax and still has the issue.

    I'll look into it some more later this week...

  • Neeraj Singh

    Neeraj Singh August 3rd, 2010 @ 10:06 AM

    • Importance changed from “” to “Low”

    I am not able to reproduce this with rails edge.

    
    ActiveRecord::Schema.define(:version => 20100803085555) do
    
      create_table "brakes", :force => true do |t|
        t.string  "name"
        t.integer "car_id"
      end
    
      create_table "cars", :force => true do |t|
        t.string "name"
      end
    
    end
    class Brake < ActiveRecord::Base
      default_scope :conditions => { :name => 'hello' }
    
      belongs_to :car
    
    end
    class Car < ActiveRecord::Base
      has_many :brakes
    end
    
    > Car.first.brakes
    
    Car Load (0.2ms)  SELECT "cars".* FROM "cars" LIMIT 1
    Brake Load (0.2ms)  SELECT "brakes"."id", "brakes"."name", "brakes"."car_id" FROM "brakes" WHERE ("brakes"."name" = 'hello') AND ("brakes".car_id = 1)
    
  • Mateo Murphy

    Mateo Murphy August 3rd, 2010 @ 03:52 PM

    Note that the issue is with has_many :through, not regular has many. However I haven't been able to reproduce the problem in a simple test, so there may be something else in my app (another gem maybe) that's causing it.

  • Neeraj Singh

    Neeraj Singh August 3rd, 2010 @ 04:01 PM

    • State changed from “new” to “invalid”

    This is with has many through.

    ree-1.8.7-2010.01 > Person.first.posts
      Person Load (0.3ms)  SELECT "people".* FROM "people" LIMIT 1
      Post Load (0.2ms)  SELECT "posts".* FROM "posts" INNER JOIN "readers" ON "posts".id = "readers".post_id WHERE ("posts"."name" = 'rails3') AND (("readers".person_id = 1))
    
    
    class Post < ActiveRecord::Base
      has_many :readers
      has_many :people, :through => :readers
    
      default_scope :conditions => {:name => 'rails3'}
    end
    
    class Person < ActiveRecord::Base
      has_many :readers
      has_many :posts, :through => :readers
    end
    

    Closing this ticket. If you are able to reproduce this case then please update this thread and the ticket will be alive again. Thanks.

  • Mateo Murphy

    Mateo Murphy August 3rd, 2010 @ 04:50 PM

    The problem I was having was that I was expecting the default_scope of the join model to be applied, which does not happen: i.e.

    class Blog < ActiveRecord::Base
      has_many :posts
      has_many :users, :through => :posts
    end
    
    class Post < ActiveRecord::Base
      default_scope :conditions => 'published_at IS NOT NULL' 
      
      belongs_to :blog
      belongs_to :user
    end
    
    class User < ActiveRecord::Base
      belongs_to :post
    end
    
    > Blog.first.posts
      Blog Load (0.3ms)  SELECT "blogs".* FROM "blogs" LIMIT 1
      Post Load (0.2ms)  SELECT "posts"."id", "posts"."name", "posts"."blog_id", "posts"."user_id", "posts"."published_at", "posts"."created_at", "posts"."updated_at" FROM "posts" WHERE (published_at IS NOT NULL) AND ("posts".blog_id = 1)
    
    > Blog.first.users
      Blog Load (0.3ms)  SELECT "blogs".* FROM "blogs" LIMIT 1
      User Load (0.2ms)  SELECT "users".* FROM "users" INNER JOIN "posts" ON "users".id = "posts".user_id WHERE (("posts".blog_id = 1))
    

    In this case, I would have expected the default scope of posts to be respected, and only the users of published posts to be returned. I'm not certain if this should be considered a bug or not, though... thoughts?

  • Neeraj Singh

    Neeraj Singh August 3rd, 2010 @ 05:08 PM

    Blog.first.users will not have the default_scope declared for Post. So technically this is not a bug :-)

  • Mateo Murphy

    Mateo Murphy August 3rd, 2010 @ 05:27 PM

    No, technically it's not a bug. But intuitively it feels like one :) it may be a feature worth exploring

  • Jan Xie

    Jan Xie November 19th, 2010 @ 05:43 AM

    What is a technically bug?

    In my understand, "default" means all my arel queries respect the default_scope I set. But has_many through create a special case of default_scope now.

  • bingbing
  • releod

    releod March 29th, 2011 @ 03:26 PM

    I am also experiencing this issue. I feel it is a valid bug, as the results are not expected - clearly by the creation of this ticket.

  • jack dempsey (jackdempsey)

    jack dempsey (jackdempsey) March 30th, 2011 @ 08:18 PM

    Just got surprised by this as well. Other threads around net have others agreeing. Anyone want to reopen this and solicit patches or a better reason to not do this?

  • Brian Underwood

    Brian Underwood April 4th, 2011 @ 03:34 PM

    I'm also having this issue. If you're defining as association with "through", the through model should be considered. Seems like a bug to me, or at least the way that it should work which may not have been previously considered. One of the things that I love about Ruby and Rails is that they work the way that you would expect them to ;)

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>

Pages