Using "find" when you have 2 has_many relations

An Account has_many Websites which in turn has_many WebsiteDomains

Now I can of course do this:
@domains = Account.find(1).websites.find(1).website_domains.find(:all)
To get all the domains for Account with id 1 and Website with id 1.

I would like to do something like this though:
@domains =
Account.find(1).websites.find(:all).website_domains.find(:all)
IE, get ALL domains for all websites in Account 1
The code above doesn’t work because of the multiple find(:all)

I could do it using :joins and :conditions I guess but then I lose other
useful stuff like attributes matching column names in the database.

Any ideas?

@domains = Domain.find(:all, :conditions => [“websites.id = ? AND
websites.account_id = ?”, website_id, acount_id], :include => “website”)

Should do it. May need to be tweaked a little.

-Nick

Oops, I forgot that I actually had one more relation that has to go in
there.
Watcher belongs_to WebsiteDomain.

So what I really would like to do is something like this:

@watcher = Watcher.find(:all, :conditions => [websites.account_id = ?",
acount_id], :include => [“website_domain”, “website”])

This does not work however and I just found this on the RoR API site:
“Itâ??s currently not possible to use eager loading on multiple
associations from the same table.”

Is that why I can not do this?

If so, any work-arounds for it?

On 1/17/06, Per Dj [email protected] wrote:

“It’s currently not possible to use eager loading on multiple
associations from the same table.”

Is that why I can not do this?

Because Rails wasn’t designed with it in mind (it doesn’t alias tables
in the SQL), and patches to implement it have been rejected (see
http://dev.rubyonrails.org/ticket/1562).

If so, any work-arounds for it?

There’s the Allow Multiple Associations Same Table plugin:
http://wiki.rubyonrails.org/rails/pages/Allow+Multiple+Associations+Same+Table+Plugin,
which is a conversion of the latest patch in the ticket mentioned
above.

The goal is to get all Watchers for one Account.
So my main problem is that since I have so many relations (Account -->
Websites --> WebsiteDomains --> Watchers) in between those two I’m not
sure how to code it in any elegant way.

Thanks for your help, really appreciate it!

I guess it comes down to what you are looking for in the final results.
Whats the end goal? A list of domains per watcher? per website? per
account?
Need some more info to be able to refine it a bit more.

-Nick

That’s a surprise :open_mouth:
Thanks for the info.

So if I want to avoid plugins and engines etc then my only choice is to
raw sql with find_by_sql ?

Looks to be the easiest way yes, but its not to painful is it?

Watcher.find_by_sql([“SELECT w.* FROM watchers w LEFT JOIN
website_domains ON website_domains.id = w.website_domain_id LEFT JOIN
websites ON websites.id = website_domains.website_id WHERE
websites.account_id = ?”, account_id])

Should do it if I got the table/column names right…

Looks to be the easiest way yes, but its not to painful is it?
No, not too painful :slight_smile:
Thanks for your help!