hudarsono
hudarsono

Reputation: 389

Rails - Joining 4 tables

Let say we have 4 tables

Client has many Campaign
Campaign has many Adgroup
Adgroup has many Ad
Ad

The relationship is the same, one to many. Let say we have known Ad.id, and we want to get Client.id from that Ad.id.

Could anybody give an elegant solution (by elegant i mean without writing sql statement, instead use active records procedure)?

Upvotes: 0

Views: 263

Answers (3)

Andrew Hacking
Andrew Hacking

Reputation: 6366

First, ensure you have your relationships setup as follows:

class Ad < ActiveRecord::Base
  belongs_to :ad_group, inverse_of: :ads
end

class AdGroup < ActiveRecord::Base
  belongs_to :campaign, inverse_of: :ad_groups
  has_many :ads, inverse_of :ad_group
end

class Campaign < ActiveRecord::Base
  belongs_to :client, inverse_of: :campaigns
  has_many :ad_groups, inverse_of :campaign
end

class Client < ActiveRecord::Base
  has_many :campaigns, inverse_of :client
end

Use joins and pluck if all you want is the client id and efficient SQL:

Client.joins(campaigns: {ad_groups: :ad}).where(
  ads: { id: some_id }).pluck('clients.id').first

If you want the entire client and efficient SQL then just:

Client.joins(campaigns: {ad_groups: :ad}).where(ads: { id: some_id }).first

Upvotes: 0

Simpleton
Simpleton

Reputation: 6415

With Rails associations, you have to remember to specify belongs_to for the other side of the relationship, so an ad will most likely has_one Adgroup and so on and so forth up the chain. Once you've coupled the associations, you can use ActiveRecord to method chain these models starting from the bottom, going up to the top of the hierarchy. So you would start with ad and chain it like:

@ad = Ad.find(an_id_or_name_or_whatever).Adgroup.Campaign.Client.id

Looking at the above, you can chain the Adgroup onto an Ad because of the associative relationship which gives you access to the methods of that parent model, all the way up to the Client model, of which .id is a method, and you can call it.

Take a look at some association basics from Rails here:

http://guides.rubyonrails.org/association_basics.html

Upvotes: 1

Andrei B&#226;rsan
Andrei B&#226;rsan

Reputation: 3521

Make sure that Ad belongs_to an Adgroup, and has a reference to it in it's db structure! Adgroups should belongs_to Campaigns and so on, all the way up. Remember, the dude with belongs_to is the one that needs to hold a reference in his db table to the guy that has_one him, not the other way round!

If the resources are created OK to begin with, you should be able to call @ad.adgroup.campaign.client.id and get a particular ad's (obtained, say, by @ad = Ad.find(some_id)) id.

Hope this helps!

Upvotes: 2

Related Questions