# How do I reference eagerly loaded Models in the View?

**URL:** <https://www.ruby-forum.com/t/how-do-i-reference-eagerly-loaded-models-in-the-view/59772>\
**Category:** Rails\
**Created:** [January 6, 2006, 5:17pm UTC](https://www.ruby-forum.com/t/how-do-i-reference-eagerly-loaded-models-in-the-view/59772 "2006-01-06T17:17:18Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![jshow](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/977dab/32.png) [@jshow](https://www.ruby-forum.com/u/jshow)\
**Post date:** [January 6, 2006, 5:17pm UTC](https://www.ruby-forum.com/t/how-do-i-reference-eagerly-loaded-models-in-the-view/59772/1 "2006-01-06T17:17:18Z")

</div>

[I hope the repost isnt’ “minded”. Following the advice of another thread I’ve changed the subject to a question. If I haven’t included important info, please ask. My database is being unduly killed. Jodi]

Cheers on-the-Rails-ers,

Before I start, I’ve read the ActiveRecord docs on eager loading, but  
for the life of me, I can’t seem to get it working.

What I mean by this, is that the eager query itself looks good (I can  
paste the  
sql dump, but it looks good to me - and runs well independantly), but it  
seems that I’m referencing the eagerly loaded data in a way that  
activerecord doesn’t understand (my assumption) - thus I’m getting a  
tonne of additional queries.

[first, the domain:  
WorkOrders has\_many: WorkOrderItems  
&&  
WorkOrderItems belongs\_to :WorkOrder  
WorkOrderItems belongs\_to :ProductsAndServices

secondly, the controller looks like:  
@work\_order = WorkOrder.find(params[:id])  
@work\_order\_items = @work\_order.WorkOrderItems.find(:all, :include  
=\> [:WorkOrder, :ProductsAndServices] )

(you’ll note that I’m eagerly loading the work\_order from the  
work\_order\_item - that’s because the WorkOrderItem model references its  
work\_order for some processing - see “pst” below)

And in the view, I reference as such:

@work\_order\_items.each {|item| @work\_order\_items\_table.data \<\<  
Hash[“Part #”, item.ProductsAndServices.part\_number,“Description”,  
item.description, “Quantity”,item.quantity, “Price”,  
number\_to\_currency(item.price), “Extended”,  
number\_to\_currency(item.sub\_total)]}

The above generates @work\_order\_items.count queries to the  
ProductsAndServices table. Why is that? Do I reference the eagerly  
loaded data incorrectly?

With the same symptom, further down in the same view I make a call to a  
WorkOrderItems method “pst” - this method references both eagerly  
referenced models - WorkOrders and ProductsAndServices using the syntax:

#calculate the line item pst  
def pst  
if (self.WorkOrder.charge\_pst? and  
self.ProductsAndServices.charge\_pst?)  
sub\_total \* 0.07  
else  
0.0  
end  
end

Again, I see that database queries are made to retrieve both WorkOrder  
and ProductsAndServices.

Probably the same problem on my part. Any ideas ninjas?

Thanx for any help.

Jodi

---

<div class="post-metadata">

**Author:** ![jshow](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/977dab/32.png) [@jshow](https://www.ruby-forum.com/u/jshow)\
**Post date:** [January 6, 2006, 6:45pm UTC](https://www.ruby-forum.com/t/how-do-i-reference-eagerly-loaded-models-in-the-view/59772/2 "2006-01-06T18:45:37Z")

</div>

your use of camelcase is confusing to read. the convention in ruby is  
to  
not use camelcase for anything other than class names… and it could  
possible be the cause of your problem.

i’ve taken the liberty to rename/organize some things, hope you don’t  
mind.

# table name : work\_orders

class WorkOrder \< AR::Base  
has\_many :work\_order\_items  
end

# table name : work\_order\_items

class WorkOrderItem \< AR::Base  
belongs\_to :work\_order  
belongs\_to :product\_or\_service  
end

# table name : product\_or\_services

class ProductOrService \< AR::Base  
has\_many :work\_order\_items  
end

—quote—  
secondly, the controller looks like:  
@work\_order = WorkOrder.find(params[:id])  
@work\_order\_items = @work\_order.WorkOrderItems.find(:all, :include =\>  
[:WorkOrder, :ProductsAndServices] )  
—end quote—

instead, why not do:

@work\_order\_items = WorkOrderItem.find(:all, :conditions =\> [  
“work\_order\_id  
= ?”, @params[:id] ], :include =\> [:work\_order, :product\_or\_service])

—quote—  
@work\_order\_items.each {|item| @work\_order\_items\_table.data \<\<  
Hash[“Part #”, item.ProductsAndServices.part\_number,  
“Description”, item.description,  
“Quantity”,item.quantity,  
“Price”, number\_to\_currency(item.price),  
“Extended”, number\_to\_currency(item.sub\_total)]}  
—end quote—

not sure what the purpose of this is…i’m assuming this is html table  
data? why not just use a partial?

fi that’s the case, then in list view:

 \<%= render :partial =\> "item", :collection =\> @work\_order\_items %\>

in \_item.rhtml:

 \<%= item.product\_or\_service.part\_number %\> \<%= item.description %\> \<%= item.quantity %\> \<%= number\_to\_currency(item.price) %\> \<%= number\_to\_currency(item.sub\_total) %\>

–quote—  
#calculate the line item pst  
def pst  
if (self.WorkOrder.charge\_pst? and  
self.ProductsAndServices .charge\_pst?)  
sub\_total \* 0.07  
else  
0.0  
end  
end  
—end quote—

again, using camelcase…try

def pst  
(work\_order.charge\_pst? and product\_or\_service.charge\_pst?) ?  
(sub\_total \*  
0.07) : 0.0  
end

hope this helps

---

<div class="post-metadata">

**Author:** ![jshow](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/977dab/32.png) [@jshow](https://www.ruby-forum.com/u/jshow)\
**Post date:** [January 7, 2006, 2:36am UTC](https://www.ruby-forum.com/t/how-do-i-reference-eagerly-loaded-models-in-the-view/59772/3 "2006-01-07T02:36:01Z")

</div>

Chris - I’ve just finally worked through your suggestions.

While they didn’t directly lead to an answer, it did serve to help me  
re-examine the problem points (plus standardize my ruby syntax (cat java

> /dev/null!).

To your benefit chris, you didn’t have all the information needed to  
come up with the solution.

I include the following, for those who can benefit. #1 is a watch-out  
(well for me anyhow), and #2 is a cool (documented)feature I discovered.

I’ve since found out the following 2 things.

1. That recursive(?) model references maybe not be handled well by AR.

@work\_order.pst\_total is a method, that looks something like:

def pst\_total  
work\_order\_items.inject(0) { |sum, item| sum + item.gst\_charge }  
end

and work\_order\_item.gst looks like

#calculate the line item gst  
def gst  
if (work\_order.charge\_gst? and products\_and\_services.charge\_gst?)  
sub\_total \* 0.08  
else  
0.0  
end  
end

As you can see that work\_order.gst, calls work\_order\_item.gst, which  
then calls work\_order.charge\_gst? (oh what a tangled web we weave!)

Anywho, the end result was work\_order\_items.count “select \* from  
work\_orders where id = ?”.

I moved the charge\_gst logic, and low and behold, lots of work\_order  
queries are toast.

1. from above, you can see

products\_and\_services is a secondary relationship to work\_orders  
[work\_orders has\_many :work\_order\_items. And :work\_order\_items  
belongs\_to :products\_and\_services].

From the work\_order class defn, I’m saving myself some queries on the  
products\_and\_services model using the following notation:

class WorkOrder \< ActiveRecord::Base  
has\_many :work\_order\_items, :include =\> [:products\_and\_services]

The :include option, from the docs  
“:include - specify second-order associations that should be eager  
loaded when the collection is loaded.”

Thus when I WorkOrder.find(), I not only get associated  
work\_order\_items, but their related products\_and\_services.

sweet!

Jodi

Chris H. wrote:

> your use of camelcase is confusing to read. the convention in ruby is  
> to  
> not use camelcase for anything other than class names… and it could  
> possible be the cause of your problem.
> 
> i’ve taken the liberty to rename/organize some things, hope you don’t  
> mind.
> 
> # table name : work\_orders
> 
> class WorkOrder \< AR::Base  
> has\_many :work\_order\_items  
> end
> 
> # table name : work\_order\_items
> 
> class WorkOrderItem \< AR::Base  
> belongs\_to :work\_order  
> belongs\_to :product\_or\_service  
> end
> 
> # table name : product\_or\_services
> 
> class ProductOrService \< AR::Base  
> has\_many :work\_order\_items  
> end
> 
> —quote—  
> secondly, the controller looks like:  
> @work\_order = WorkOrder.find(params[:id])  
> @work\_order\_items = @work\_order.WorkOrderItems.find(:all, :include =\>  
> [:WorkOrder, :ProductsAndServices] )  
> —end quote—
> 
> instead, why not do:
> 
> @work\_order\_items = WorkOrderItem.find(:all, :conditions =\> [  
> “work\_order\_id  
> = ?”, @params[:id] ], :include =\> [:work\_order, :product\_or\_service])
> 
> —quote—  
> @work\_order\_items.each {|item| @work\_order\_items\_table.data \<\<  
> Hash[“Part #”, item.ProductsAndServices.part\_number,  
> “Description”, item.description,  
> “Quantity”,item.quantity,  
> “Price”, number\_to\_currency(item.price),  
> “Extended”, number\_to\_currency(item.sub\_total)]}  
> —end quote—
> 
> not sure what the purpose of this is…i’m assuming this is html table  
> data? why not just use a partial?
> 
> fi that’s the case, then in list view:
> 
> \<%= render :partial =\> "item", :collection =\> @work\_order\_items %\>
> 
> in \_item.rhtml:
> 
> \<%= item.product\_or\_service.part\_number %\> \<%= item.description %\> \<%= item.quantity %\> \<%= number\_to\_currency(item.price) %\> \<%= number\_to\_currency(item.sub\_total) %\>
> 
> –quote—  
> #calculate the line item pst  
> def pst  
> if (self.WorkOrder.charge\_pst? and  
> self.ProductsAndServices .charge\_pst?)  
> sub\_total \* 0.07  
> else  
> 0.0  
> end  
> end  
> —end quote—
> 
> again, using camelcase…try
> 
> def pst  
> (work\_order.charge\_pst? and product\_or\_service.charge\_pst?) ?  
> (sub\_total \*  
> 0.07) : 0.0  
> end
> 
> hope this helps
