# Simpe, but basic active record question

**URL:** <https://www.ruby-forum.com/t/simpe-but-basic-active-record-question/67096>\
**Category:** Rails\
**Created:** [August 31, 2006, 4:27pm UTC](https://www.ruby-forum.com/t/simpe-but-basic-active-record-question/67096 "2006-08-31T16:27:44Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![remcoh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/c37758/32.png) [@remcoh](https://www.ruby-forum.com/u/remcoh)\
**Post date:** [August 31, 2006, 4:27pm UTC](https://www.ruby-forum.com/t/simpe-but-basic-active-record-question/67096/1 "2006-08-31T16:27:44Z")

</div>

Hi,  
I know i can do this:  
if i have an ordeline i can do:

customername=orderline.order.customer.name

but can i also go the other way around?  
lets say i have a customer and i want to get a hold of all orderlines

orderlines=customer.orders.orderlines would be great, but that doesn’t  
work

is there a smart way to do this or do i have to use a plain sql query  
like:

select customer from customers,orders,orderlines where  
customer.customer\_id=orders.customer\_id and  
orderline.order\_id=order.order\_id

the above doesn’t look very rails-like, thefore i am asking…

Remco

---

<div class="post-metadata">

**Author:** ![remcoh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/c37758/32.png) [@remcoh](https://www.ruby-forum.com/u/remcoh)\
**Post date:** [August 31, 2006, 6:37pm UTC](https://www.ruby-forum.com/t/simpe-but-basic-active-record-question/67096/2 "2006-08-31T18:37:44Z")

</div>

Remco Hh wrote:

> Hi,  
> I know i can do this:  
> if i have an ordeline i can do:
> 
> customername=orderline.order.customer.name
> 
> but can i also go the other way around?  
> lets say i have a customer and i want to get a hold of all orderlines
> 
> orderlines=customer.orders.orderlines would be great, but that doesn’t  
> work
> 
> is there a smart way to do this or do i have to use a plain sql query  
> like:
> 
> select customer from customers,orders,orderlines where  
> customer.customer\_id=orders.customer\_id and  
> orderline.order\_id=order.order\_id
> 
> the above doesn’t look very rails-like, thefore i am asking…
> 
> Remco

As long as your associations are set up properly, you sure can do that.  
However not exactly the way you expect.

customer.orders returns an array of orders, and an array does not have a  
‘orderlines’ method. You should access it like this instead

customer.orders.each do |order|  
do\_something\_with(order)  
order.orderlines.each do |ol|  
do\_something\_else\_with(ol)  
end  
end

Or if you really want all the orderlines from all orders for a customer  
lumped together in one big array, you can do:

orderlines = []  
costomer.orders.each do |order|  
orderlines += order.orderlines  
end

---

<div class="post-metadata">

**Author:** ![remcoh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/c37758/32.png) [@remcoh](https://www.ruby-forum.com/u/remcoh)\
**Post date:** [August 31, 2006, 6:42pm UTC](https://www.ruby-forum.com/t/simpe-but-basic-active-record-question/67096/3 "2006-08-31T18:42:34Z")

</div>

Remco Hh \<rails-mailing-list@…\> writes:

> orderlines=customer.orders.orderlines would be great, but that doesn’t  
> work

The problem is that customer.orders works, but returns a collection of  
orders.  
And a _collection_ doesn’t have any orderlines.

A good bet would be customer.orders.collect{|o| o.orderlines} which  
would  
collect the orderlines from all of the orders and return them.

You’d end up with an array of arrays (this will only make sense in a  
fixed width  
font:)

## ------- order 1 ------- - order 2 - , ------------- order 3

[[orderline1, orderline2], [orderline3], [orderline4, orderline5,  
orderline6] ]

if you only want the orderlines then you can call  
customer.orders.collect{|o| o.orderlines}.flatten which will collapse  
the above  
into one big array.

---

<div class="post-metadata">

**Author:** ![remcoh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/c37758/32.png) [@remcoh](https://www.ruby-forum.com/u/remcoh)\
**Post date:** [August 31, 2006, 6:52pm UTC](https://www.ruby-forum.com/t/simpe-but-basic-active-record-question/67096/4 "2006-08-31T18:52:56Z")

</div>

Thanks Gareth and Alex.

I get this, but i don’t really like it because if you compare it with  
how i do it in the sql example, i only use one query with joines to get  
the results. In your examples you create a loop (iterator) which submits  
multiple queries

so, if there is no other method, i think i’ll just use plain old mysql  
I was convinced rails had a better method…

regards,

remco

Alex W. wrote:

> Remco Hh wrote:
> 
> > Hi,  
> > I know i can do this:  
> > if i have an ordeline i can do:
> > 
> > customername=orderline.order.customer.name
> > 
> > but can i also go the other way around?  
> > lets say i have a customer and i want to get a hold of all orderlines
> > 
> > orderlines=customer.orders.orderlines would be great, but that doesn’t  
> > work
> > 
> > is there a smart way to do this or do i have to use a plain sql query  
> > like:
> > 
> > select customer from customers,orders,orderlines where  
> > customer.customer\_id=orders.customer\_id and  
> > orderline.order\_id=order.order\_id
> > 
> > the above doesn’t look very rails-like, thefore i am asking…
> > 
> > Remco
> 
> As long as your associations are set up properly, you sure can do that.  
> However not exactly the way you expect.
> 
> customer.orders returns an array of orders, and an array does not have a  
> ‘orderlines’ method. You should access it like this instead
> 
> customer.orders.each do |order|  
> do\_something\_with(order)  
> order.orderlines.each do |ol|  
> do\_something\_else\_with(ol)  
> end  
> end
> 
> Or if you really want all the orderlines from all orders for a customer  
> lumped together in one big array, you can do:
> 
> orderlines = []  
> costomer.orders.each do |order|  
> orderlines += order.orderlines  
> end

---

<div class="post-metadata">

**Author:** ![remcoh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/c37758/32.png) [@remcoh](https://www.ruby-forum.com/u/remcoh)\
**Post date:** [August 31, 2006, 7:17pm UTC](https://www.ruby-forum.com/t/simpe-but-basic-active-record-question/67096/5 "2006-08-31T19:17:03Z")

</div>

Remco Hh wrote:

> Thanks Gareth and Alex.
> 
> I get this, but i don’t really like it because if you compare it with  
> how i do it in the sql example, i only use one query with joines to get  
> the results. In your examples you create a loop (iterator) which submits  
> multiple queries
> 
> so, if there is no other method, i think i’ll just use plain old mysql  
> I was convinced rails had a better method…
> 
> regards,
> 
> remco

You can use eager loading to make so only one query is needed.

class Customer  
has\_many :orders, :include =\> :orderlines  
end

This will put a LEFT OUTER JOIN in your SQL and fetch all associated  
orderlines along with the orders. Then customer.order.first.orderlines  
will not generate a query.

---

<div class="post-metadata">

**Author:** ![remcoh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/c37758/32.png) [@remcoh](https://www.ruby-forum.com/u/remcoh)\
**Post date:** [August 31, 2006, 7:04pm UTC](https://www.ruby-forum.com/t/simpe-but-basic-active-record-question/67096/6 "2006-08-31T19:04:40Z")

</div>

On 8/31/06, Remco Hh [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> orderlines=customer.orders.orderlines would be great, but that doesn’t  
> work

customer.orders.orderlines.find(:all) may do the trick?

Isak

---

<div class="post-metadata">

**Author:** ![remcoh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/c37758/32.png) [@remcoh](https://www.ruby-forum.com/u/remcoh)\
**Post date:** [August 31, 2006, 7:40pm UTC](https://www.ruby-forum.com/t/simpe-but-basic-active-record-question/67096/7 "2006-08-31T19:40:44Z")

</div>

> so, if there is no other method, i think i’ll just use plain old mysql  
> I was convinced rails had a better method…

If you need the lines for for a given order, why not just do something  
like this:

@order = @customer.orders.find(order\_id, :include =\> :order\_lines)

That’ll use 1 query - the lines for that order will be accessible via  
@order.order\_lines.

Steve

---

<div class="post-metadata">

**Author:** ![remcoh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/c37758/32.png) [@remcoh](https://www.ruby-forum.com/u/remcoh)\
**Post date:** [August 31, 2006, 7:37pm UTC](https://www.ruby-forum.com/t/simpe-but-basic-active-record-question/67096/8 "2006-08-31T19:37:36Z")

</div>

Isak H. wrote:

> On 8/31/06, Remco Hh [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > orderlines=customer.orders.orderlines would be great, but that doesn’t  
> > work
> 
> customer.orders.orderlines.find(:all) may do the trick?
> 
> Isak

i dont’t think this wil work…

---

<div class="post-metadata">

**Author:** ![remcoh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/c37758/32.png) [@remcoh](https://www.ruby-forum.com/u/remcoh)\
**Post date:** [August 31, 2006, 8:19pm UTC](https://www.ruby-forum.com/t/simpe-but-basic-active-record-question/67096/9 "2006-08-31T20:19:34Z")

</div>

If you really want to NOT loop on the orders, you could do the  
following:

orders = Customer.orders.collect{|o| o.id}  
lines = OrderLine.find(:all, :conditions =\> [‘order\_id = (?)’,orders])

-Lonnie

Remco Hh wrote:

> Thanks Gareth and Alex.
> 
> I get this, but i don’t really like it because if you compare it with  
> how i do it in the sql example, i only use one query with joines to get  
> the results. In your examples you create a loop (iterator) which submits  
> multiple queries
> 
> so, if there is no other method, i think i’ll just use plain old mysql  
> I was convinced rails had a better method…
> 
> regards,
> 
> remco
