# Newb - Active Records question

**URL:** <https://www.ruby-forum.com/t/newb-active-records-question/77429>\
**Category:** Rails\
**Created:** [November 27, 2006, 11:02pm UTC](https://www.ruby-forum.com/t/newb-active-records-question/77429 "2006-11-27T23:02:15Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![canner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/f9ae1b/32.png) [@canner](https://www.ruby-forum.com/u/canner)\
**Post date:** [November 27, 2006, 11:02pm UTC](https://www.ruby-forum.com/t/newb-active-records-question/77429/1 "2006-11-27T23:02:15Z")

</div>

Can you sort a result set? I’d like to have a generic query, but be  
able to order it by one of the cols if a param is set.

ie  
@records = Cars.find(:all, :conditions =\> [“color = ‘Red’”], :order =\>  
“sales” )  
@records.Orderby(“Year”)

---

<div class="post-metadata">

**Author:** ![canner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/f9ae1b/32.png) [@canner](https://www.ruby-forum.com/u/canner)\
**Post date:** [November 27, 2006, 11:32pm UTC](https://www.ruby-forum.com/t/newb-active-records-question/77429/2 "2006-11-27T23:32:06Z")

</div>

Sure, a result set is really just an array of model objects, so you can  
do something like:

@records.sort\_by {|record| record.year}

but why wouldn’t you just do the sort in the find? Your original code  
retrieves the records ordered by sales and then immediately discards  
that order to reorder by year. It makes more sense to just retrieve the  
records in the order you want in the first place:

if param\_is\_set  
@records = Cars.find(:all, :conditions =\> [‘color = ?’, ‘red’], :order  
=\> ‘year’)  
else  
@records = Cars.find(:all, :conditions =\> [‘color = ?’, ‘red’], :order  
=\> ‘sales’)  
end

---

<div class="post-metadata">

**Author:** ![canner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/f9ae1b/32.png) [@canner](https://www.ruby-forum.com/u/canner)\
**Post date:** [November 30, 2006, 5:19pm UTC](https://www.ruby-forum.com/t/newb-active-records-question/77429/3 "2006-11-30T17:19:10Z")

</div>

Thanks for the tip Chris.

The reason I wanted to know how to sort was in a few instances I need  
information that would come from the same set of data but sorted  
differently. Just trying to skip a few trips to the DB.

If I can ask another question, how do you simplify this:

cars  
id, model\_id,…

models  
id, description…

and if I want to have the query pull in that model description how would  
I do so? Currenly I was using joins, but thought Active Record must  
have a better way of doing so.

@records = Car.find(:all,  
:select =\> " cars.\*, model.description",  
:joins =\> " models",  
:conditions =\> [‘color = ? AND models.id = cars.model\_id’, ‘red’],  
:order =\> ‘year’)

It works, but looks fugly.

---

<div class="post-metadata">

**Author:** ![canner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/f9ae1b/32.png) [@canner](https://www.ruby-forum.com/u/canner)\
**Post date:** [November 30, 2006, 6:06pm UTC](https://www.ruby-forum.com/t/newb-active-records-question/77429/4 "2006-11-30T18:06:16Z")

</div>

Alex T. wrote:

> @records = Car.find(:all,  
> :select =\> " cars.\*, model.description",  
> :joins =\> " models",  
> :conditions =\> [‘color = ? AND models.id = cars.model\_id’, ‘red’],  
> :order =\> ‘year’)
> 
> It works, but looks fugly.

Yep, that’s definitely more complicated than it needs to be. All you  
need to do is:

@records = Car.find(:all,  
:include =\> :model,  
:conditions =\> [‘color = ?’, ‘red’],  
:order =\> ‘year’)

ActiveRecord will create the join for you. (You can also leave the  
select line as you had it, if you want to make sure no other columns  
from the models table get loaded for some reason.)

Just make sure you have belongs\_to :model in your Car model and has\_many  
:cars in your Model … uh … model. 😃

Hope this helps!

---

<div class="post-metadata">

**Author:** ![canner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/f9ae1b/32.png) [@canner](https://www.ruby-forum.com/u/canner)\
**Post date:** [November 30, 2006, 8:08pm UTC](https://www.ruby-forum.com/t/newb-active-records-question/77429/5 "2006-11-30T20:08:02Z")

</div>

Hmm, its not quite working how I expected.

I put the has and belongs to in the model, and even after a reboot I get  
the following:  
test = Cars.find(:all, :include =\> :make, :conditions =\> […])

:I changed Model to Make, just to make things a little less murky

and when I run a debug on the screen I see:

- !ruby/object:Car  
attributes:  
model\_id: 2322  
id: 3551  
date: 2006-11-03 00:00:00 -06:00  
…  
Make: &id001 !ruby/object:Make  
attributes:  
description: “BMW”  
id: 2322

- !ruby/object:Car  
attributes:  
model\_id: 2322  
id: 3547  
date: 2006-11-03 00:00:00 -06:00  
Make: \*id001

- !ruby/object:Car  
attributes:  
employee\_id: 2457  
id: 3583  
pay\_date: 2006-12-03 00:00:00 -06:00  
pay\_type\_id: 4  
active: 1  
Make: &id002 !ruby/object:Employee  
attributes:  
id: 2457  
description: “Buick”

Which pulls in the info, but if I try to access the data  
\<% test.each do |x| %\>  
\<%= x.description %\>  
\<% end %\>

I get  
“undefined method `description’ for #Car:0x2afab44d08b8”

but the following works  
\<% test.each do |x| %\>  
\<%= x.make.description %\>  
\<% end %\>

Any way to do this w/o having to write the ‘make’ in there? I can  
rewrite my code, just wondering if there is another way to do this.

Thanks

Alex

---

<div class="post-metadata">

**Author:** ![canner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/f9ae1b/32.png) [@canner](https://www.ruby-forum.com/u/canner)\
**Post date:** [November 30, 2006, 11:37pm UTC](https://www.ruby-forum.com/t/newb-active-records-question/77429/6 "2006-11-30T23:37:12Z")

</div>

Alex T. wrote:

> but the following works  
> \<% test.each do |x| %\>  
> \<%= x.make.description %\>  
> \<% end %\>
> 
> Any way to do this w/o having to write the ‘make’ in there? I can  
> rewrite my code, just wondering if there is another way to do this.

You could probably do it by defining your own “description” method in  
your Car model, but in my opinion, you’ll be much better off in the long  
run changing your code to the way you have it above. This is the  
standard way to access columns in related tables, and sticking to it  
will make it easier for other people to read your code, and for you to  
read other people’s code.

It more accurately reflects your actual database structure: your cars  
table doesn’t have a description, but it does have a make (through the  
make\_id column), and your make table has a description column. So, car  
-\> make -\> description … which matches up perfectly in your ruby code  
with car.make.description. Does this make sense?

---

<div class="post-metadata">

**Author:** ![canner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/f9ae1b/32.png) [@canner](https://www.ruby-forum.com/u/canner)\
**Post date:** [December 1, 2006, 7:07pm UTC](https://www.ruby-forum.com/t/newb-active-records-question/77429/7 "2006-12-01T19:07:47Z")

</div>

Yep, that is crystal clear. With that being the standard way of writing  
the code, I will just plan on changing things to that style.

By all means tell me to stop bugging you at any point, but heres another  
one.

I have an employees table, and another table (sales) references it…  
twice.  
so I have an employee\_id, and supervisor columns, both of which are just  
employee\_id numbers.

So if I wanted to write a query to get their names, how would I do it?

this would work for one column:  
@records = Sale.find(:all,  
:include =\> :employee, #matches on employee\_id column  
)

but how to do the second?

---

<div class="post-metadata">

**Author:** ![canner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/f9ae1b/32.png) [@canner](https://www.ruby-forum.com/u/canner)\
**Post date:** [November 30, 2006, 6:18pm UTC](https://www.ruby-forum.com/t/newb-active-records-question/77429/8 "2006-11-30T18:18:37Z")

</div>

sweet, thanks again!

Just to ask it right away, if you have more tables would it be

@records = Car.find(:all,  
:include =\> :model,  
:include =\> :engine,  
:conditions =\> [‘color = ?’, ‘red’],  
:order =\> ‘year’)

or more like  
@records = Car.find(:all,  
:include =\> [:model, :engine],  
:conditions =\> [‘color = ?’, ‘red’],  
:order =\> ‘year’)

or something else?

> Just make sure you have belongs\_to :model in your Car model and has\_many  
> :cars in your Model … uh … model. 😃

yeah, for examples, I should pick better names sometimes. =P

Chris G. wrote:

> Alex T. wrote:
> 
> > @records = Car.find(:all,  
> > :select =\> " cars.\*, model.description",  
> > :joins =\> " models",  
> > :conditions =\> [‘color = ? AND models.id = cars.model\_id’, ‘red’],  
> > :order =\> ‘year’)
> > 
> > It works, but looks fugly.
> 
> Yep, that’s definitely more complicated than it needs to be. All you  
> need to do is:
> 
> @records = Car.find(:all,  
> :include =\> :model,  
> :conditions =\> [‘color = ?’, ‘red’],  
> :order =\> ‘year’)
> 
> ActiveRecord will create the join for you. (You can also leave the  
> select line as you had it, if you want to make sure no other columns  
> from the models table get loaded for some reason.)
> 
> Just make sure you have belongs\_to :model in your Car model and has\_many  
> :cars in your Model … uh … model. 😃
> 
> Hope this helps!
