help with :include on active record finds

Hi All,

I am having trouble getting the :include option to work on my active record finds. They are not eager loading, adding the joins to the sql queries. Has anyone had this problem? Here is my query:

@cart = Cart.find_by_id(session[:cart_id], :include => [:cart_items])

This is generating the following query: SELECT * FROM carts WHERE (carts.id = 23) LIMIT 1

Rails is not eager loading the cart_items which belongs_to cart. Does anyone know why?

Thanks,

Sean

Hi All, I am having trouble getting the :include option to work on my active record finds. They are not eager loading, adding the joins to the sql queries. Has anyone had this problem? Here is my query:

   @cart = Cart.find_by_id(session[:cart_id], :include => [:cart_items])

This is generating the following query: SELECT * FROM `carts` WHERE (`carts`.`id` = 23) LIMIT 1

Rails is not eager loading the cart_items which belongs_to cart. Does anyone know why?

Don't think it can. Not in a single query. You have one cart that has many items. You can't return all of that in a single query unless you want to send duplicate rows for the cart for every row of the cart item.

There may be right after that line in the logs a line fetching the cart items. Or Rails might not do it since it's not possible.

If I'm thinking clearly that is :slight_smile:

Nah, that should work I think--see the "Eager Loading" section on http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethod s.html

I just tried this out in a toy app of my own, and was surprised to see in my log that *in addition* to the left-join query immediately under the heading "Processing OrganizationsController#show", there were 3 other queries that followed the heading "Rendering organizations/show". One was triggered by (I think) this line in my view:

  <% if @organization.people.count > 0 %>

That generated a:

  SELECT count(*) AS count_all FROM `people` WHERE (people.organization_id = 1)

Then I have 2 instances of:

  SELECT * FROM `organizations` WHERE (`organizations`.`id` = 1)

Which I believe are caused by resolving the person.organization.name calls in the part of the view that lists the people belonging to @organization.

So... not that this isn't a bit dismaying, BUT--is there any chance that you too are looking at calls generated not by your find_by_id call, but by subsequent view activity?

Cheers,

-Roy

I don’t think it has to do with view activity, because the cart and cart_items queries are generated by a before_filter… and the are only run once. Plus, they are instantiating the @cart and it’s .cart_items children, so I don’t think any view methods would affect that. Maybe in your case you can call @organization.people.size to avoid the sql. There are other finds in my site that aren’t generating the eager loading queries like I would expect (and I believe rails used to, prior to rails 2.0.2).

Here’s the kind of query I would expect rails to generated based on the find statement:

Eager loading in rails 2.1 changed: Mixing :include and :conditions - Space Vatican

Fred

Ah--you're right about changing .count to .size. That does dissappear the count(*) query. Thanks!

Like I say--I do get the LEFT JOIN query. It's not as pretty as yours, but it's there:

  SELECT `organizations`.`id` AS t0_r0,         `organizations`.`name` AS t0_r1,         `organizations`.`abbreviation` AS t0_r2,         `organizations`.`city` AS t0_r3,         `organizations`.`state` AS t0_r4,         `organizations`.`crn_site` AS t0_r5,         `organizations`.`created_at` AS t0_r6,         `organizations`.`updated_at` AS t0_r7,         `people`.`id` AS t1_r0,         `people`.`first_name` AS t1_r1,         `people`.`last_name` AS t1_r2,         `people`.`birth_date` AS t1_r3,         `people`.`organization_id` AS t1_r4,         `people`.`created_at` AS t1_r5,         `people`.`updated_at` AS t1_r6   FROM `organizations` LEFT OUTER JOIN        `people`   ON people.organization_id = organizations.id WHERE (`organizations`.`id` = '1')

That's with rails 2.0.2 and mysql. What's your version & db?

(There's no chance that you left off the 'has_many :cart_items' declaration in your cart class is there?)

Hi All, I am having trouble getting the :include option to work on my
active record finds. They are not eager loading, adding the joins to the sql
queries. Has anyone had this problem? Here is my query:

@cart = Cart.find_by_id(session[:cart_id], :include =>
[:cart_items])

This is generating the following query: SELECT * FROM `carts` WHERE (`carts`.`id` = 23) LIMIT 1

Rails is not eager loading the cart_items which belongs_to cart.
Does anyone know why?

Don't think it can. Not in a single query. You have one cart that
has many items. You can't return all of that in a single query unless you want to send duplicate rows for the cart for every row of the cart
item.

That's what Rails used to do :slight_smile:

Fred