Forum: Ruby on Rails ActiveRecord associations

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
5d15c6821f3c3054c04b85471824ba7c?d=identicon&s=25 Richard Williams (Guest)
on 2006-05-11 16:09
(Received via mailing list)
Can someone clarify this for me?  Suppose I have two tables like:

class Company < ActiveRecord::Base
   belongs_to :category
end

class Category < ActiveRecord::Base
   has_many :companies
end

I understand that the belongs_to causes related companies to be read
from the db when I ask for a category.  I suspect SQL something like

  select * from categories, companies
  where category.id = myid
    and companies.category_id = category.id

but what SQL results from the has_many?
882cc23c77c5c6d27613c51396a02a0d?d=identicon&s=25 Stephen Bartholomew (Guest)
on 2006-05-11 16:15
(Received via mailing list)
You can look at the development.log file to see all the SQL queries made
but it's probably like the query you said:

belongs_to:
select * from categories where category_id = {company_category_id}
- where category id is retrived from the company results

has_many:
select * from companies where category_id = {category_id}
- where category id is the id of the retrived category

Steve
7c4087d053eb02d099a17d91ba5e33b5?d=identicon&s=25 Brian Hughes (Guest)
on 2006-05-11 16:28
(Received via mailing list)
On May 11, 2006, at 10:08 AM, Richard Williams wrote:
> I understand that the belongs_to causes related companies to be read
> from the db when I ask for a category.  I suspect SQL something like
>
>   select * from categories, companies
>   where category.id = myid
>     and companies.category_id = category.id
>
> but what SQL results from the has_many?

I would say that you are thinking about this in the wrong way.
Technically the belong_to and the has_many methods don't specifically
create SQL. What they do is create a programatic link between the two
models that is then expressed as SQL when you request specific data
from the database.

If you do: Company.find(:first), say through script/console, SQL is
generated, but no SQL specific to the belongs_to relationship.

If you do: Company.find(:first).category, you actually create two SQL
requests to the database. The first is to return the first Company
record. The second is to return the parent Category record of that
Company record.

Likewise, if you do: Category.find(:first).companies, you get 2 SQL
requests, the second of which brings back an array of child Company
records.

If you want a deeper understanding of this, there are several things
you should do. First, I recommend getting the Agile Web Development
with Rails book (http://pragmaticprogrammer.com/).

Second, you should read through the API docs on this page:
     <http://rails.rubyonrails.com/classes/ActiveRecord/...
ClassMethods.html>

Third, you should launch your Rails app under Development, with the
ability to see the WEBrick/lighttpd output, launch script/console and
give some find calls a try, looking at the web server output. In that
output will be the SQL generated by Rails.

-Brian
5d15c6821f3c3054c04b85471824ba7c?d=identicon&s=25 Richard Williams (Guest)
on 2006-05-11 16:31
(Received via mailing list)
On Thursday, May 11, 2006, at 3:15 PM, Stephen Bartholomew wrote:
>
>> class Category < ActiveRecord::Base
>> but what SQL results from the has_many?
>>
>_______________________________________________
>Rails mailing list
>Rails@lists.rubyonrails.org
>http://lists.rubyonrails.org/mailman/listinfo/rails


So I guess that if you don't ever want to do the has_many query, i.e.
you don't every want to get a list of categories for a particular set of
companies you would not need to have the has_many association in the
model.
7c4087d053eb02d099a17d91ba5e33b5?d=identicon&s=25 Brian Hughes (Guest)
on 2006-05-11 16:38
(Received via mailing list)
On May 11, 2006, at 10:29 AM, Richard Williams wrote:
>> select * from companies where category_id = {category_id}
>> - where category id is the id of the retrived category
>
> So I guess that if you don't ever want to do the has_many query, i.e.
> you don't every want to get a list of categories for a particular
> set of
> companies you would not need to have the has_many association in
> the model.

Not true, IMO. Unfortunately, while Stephen's description is
essentially accurate, it's too simplistic a view into what
ActiveRecord associations can do for you. If you have a relationship
where it makes sense to say one model belongs_to another model, the
"parent" model should have the appropriate has_* association
specified within it.

I believe it would technically work, if you only specified one side
of the association, you would be cutting off half (or more) of the
functionality that ActiveRecord is trying to provide. I would say
it's actually irrelevant if the code you are currently planning to
develop only accesses the association from one side, you want to have
both sides specified so that when you need both sides, it will be there.

-Brian
882cc23c77c5c6d27613c51396a02a0d?d=identicon&s=25 Stephen Bartholomew (Guest)
on 2006-05-11 16:38
(Received via mailing list)
As Brian said, has_many defines a relationship - it doesn't generate
SQL. There is more involved in this relationship that just selecting out
  children, such as creating and deleting related records.

Also, the query to select children wont be run unless you try to do
something with them:

for company in @category.companies
   # ... code
end

I also second all of Brian's advice.

Cheers,

Steve
5d15c6821f3c3054c04b85471824ba7c?d=identicon&s=25 Richard Williams (Guest)
on 2006-05-11 16:39
(Received via mailing list)
Thanks Brian.

What I was confused about was that I _never_ see example model where
ONLY a has_many or ONLY a belongs to is shown.  Always they are shown as
a pair.  I wanted to know if it is "normal" to use only one or the other
and when that would be.

I think I understand now that you can use either one independently of
the other or you can use both together as required by the application.
This topic is locked and can not be replied to.