Belong to and search


#1

Hi,

I’m trying to understand belongs_to and has_many etc… I understand the
relationship but I’m trying to figure how this can help me

for example I have two tables
i have 2 tables called mothers and another called childrens
in this childrens model i have this

###Childrens model
belongs_to: mother

now in the
children controller
I want to retrive the mother name currently I’m doing this way

def index ##show all the childrens and their mother’s name
@childrens = Childrens.find(
:all,
:select=>"mothers.name AS mother_name, childrens.* ",
:join=>“LEFT JOIN mothers ON mothers.id = childrens.mother_id”
)
end

I was just curious because of the belongs_to I can skip this left join
on tables


#2

If you have set up the associations (belongs_to and has_many) then if
you
have a Child object child you can just say child.mother to get the
mother.
Similarly if you have a mother object you can say mother.children to get
the
children. It is all done by magic.
Colin

2009/5/12 Anthony W. removed_email_address@domain.invalid


#3

Hi

thanks works like a charm!

but i’m just curious performance wise
when I look at mongrel it seems that there are two queries
first the children.all()
then for each record it does a new query for mother get name…

now is that as quick compare to juts one query with a left join and get
all the data in children().

Colin L. wrote:

If you have set up the associations (belongs_to and has_many) then if
you
have a Child object child you can just say child.mother to get the
mother.
Similarly if you have a mother object you can say mother.children to get
the
children. It is all done by magic.
Colin

2009/5/12 Anthony W. removed_email_address@domain.invalid


#4

2009/5/12 Anthony W. removed_email_address@domain.invalid

now is that as quick compare to juts one query with a left join and get
all the data in children().

If you know you are going to be accessing the associated objects use
:include in the find to tell Rails to fetch all the data in one query,
so
something like
@children = Child.find(:all, :include => :mother)

By the way, I think the class should be Child, the table children and
the
controller children_controller.
Rails should know that children is the plural of child.

If you are really building a database of family relationships then you
might
want to search for a thread here a few weeks ago about how to organise
the
db. There were some very interesting ideas discussed.

Colin


#5

2009/5/12 Anthony W. removed_email_address@domain.invalid

Hi thank you

so if I use the include
how do i just retrieve the name then

Do you mean you want a query finding the child, including the
mother.namebut not the other mother fields? I do not know whether you
can do that. I
think the overhead of fetching all columns is going to be rather small.
Colin


#6

Hi thank you

so if I use the include
how do i just retrieve the name then

example this is using the “magic way”

@children do |child|

… print child.mother.name

end


#7

If you want to retrieve just the name, than use the :select option
with your find:

@children = Child.find(:all, :include => :mother, :select => ‘name’)


#8

2009/5/12 pharrington removed_email_address@domain.invalid

If you want to retrieve just the name, than use the :select option
with your find:

@children = Child.find(:all, :include => :mother, :select => ‘name’)

Does that select child.name or mother.name?
Colin


#9

Yeah I deleted that post immediately after because that selects
child.name. Something like :select => “mothers.name AS mother_name”
would probably work, but just ugly AND then you’d need a mother_name
virtual attribute in the Child model, making things rather needlessly
horrific. I really can’t think of a good way (without raw SQL) to do
this in one query either.


#10

OK I’m dumb; you definitely don’t need a virtual attribute for that
(not really sure what i was thinking), but its still ugly probably not
worth doing.