ActiveRecord: Nested :include erroneous behavior

Hi, Found a simple example breaking on moving to 2.2 from 2.0. This example illustrates the usage of nested :include finder options.

class Book < ActiveRecord::Base   has_many :distributors end

class Distributor < ActiveRecord::Base   belongs_to :book   has_many :agents end

class Agent < ActiveRecord::Base   belongs_to :distributor   has_many :shops end

class Shop < ActiveRecord::Base   belongs_to :agent end

Schema - http://pastie.org/426261

def test_should_load_avatars   shop_1= Shop.create!   shop_2= Shop.create!   book= Book.create!(:distributors => [Distributor.create!(:agents=> [Agent.create!(:shops => [shop_2, shop_2])])])

  loaded_version = Book.find(book.id, :include => [:distributors => {:agents => :shops}], :order => 'shops.id')

  assert(loaded_version.distributors.first.agents.first.shops.size == 2) #THIS ASSERTION FAILS WITH SHOPS.SIZE BEING 1, INSTEAD OF 2 end

On some investigation, I found that the query fired was correct, but Rails was unable to instantiate the 'shops' collection properly.

Any help on this issue would be appreciated.

Thanks

def test_should_load_avatars shop_1= Shop.create! shop_2= Shop.create! book= Book.create!(:distributors => [Distributor.create!(:agents=> [Agent.create!(:shops => [shop_2, shop_2])])])

loaded_version = Book.find(book.id, :include => [:distributors => {:agents => :shops}], :order => 'shops.id')

assert(loaded_version.distributors.first.agents.first.shops.size == 2) #THIS ASSERTION FAILS WITH SHOPS.SIZE BEING 1, INSTEAD OF 2 end

On some investigation, I found that the query fired was correct, but Rails was unable to instantiate the 'shops' collection properly.

The problem is not to do with the nested-ness of the includes but because you have an agent with the same shop twice (the line in question that removes duplicates is

Fred

Bad paste. The problem again. Looks like it is a problem only when there is a has_one relationship.

class Book < ActiveRecord::Base has_one :distributor end

class Distributor < ActiveRecord::Base belongs_to :book has_many :agents end

class Agent < ActiveRecord::Base belongs_to :distributor has_many :shops end

class Shop < ActiveRecord::Base belongs_to :agent end

Schema - http://pastie.org/426261

def test_should_load_avatars shop_1= Shop.create! shop_2= Shop.create! book= Book.create!(:distributor => Distributor.create!(:agents=> [Agent.create!(:shops => [shop_1, shop_2])]))

loaded_version = Book.find(book.id, :include => [:distributor => {:agents => :shops}], :order => ‘shops.id’)

assert(loaded_version.distributor.agents.first.shops.size == 2) #THIS ASSERTION FAILS WITH SHOPS.SIZE BEING 1, INSTEAD OF 2 end

This fails on Rails 2.2.2. Any help on this would be much appreciated, Akshay

Created a ticket for this issue at - http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/2341

Bad paste. The problem again. Looks like it is a problem only when there is
a has_one relationship.

Do you need all these models/associations or is there a small test case that fails ?

Fred

Thanks for looking at it.

A one file test - http://pastie.org/426840

Another thing I saw was that the that test passes when :include is replaced with :joins.

Thanks for looking at it.A one file test -http://pastie.org/426840

Another thing I saw was that the that test passes when :include is replaced with :joins.

Not surprising - in that case the association isn't eager loaded at all. If it passes without the order clause then you've narrowed it down to the joins based include mechanism.

Fred

Yup, it passes without the :order option, indicating that there is a problem with the join based mechanism.

Thanks

So is this a valid Rails bug ? Should I create a ticket for it on Lighthouse ?

So is this a valid Rails bug ? Should I create a ticket for it on Lighthouse ?

Seems like you already have :-). I'd definitely check against 2.3.2 - I remember there being a fix for a :include bug somewhere.

Fred

Just checked, this test fails on Rails 2.3.2 too.

Thanks for looking into it.

The ticket is at https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/2341-nested-finder-include-option-with-has_one#ticket-2341-4

Not sure how the ticket assignment thing works :wink:

Thanks