2012-01-25 59 views
0

让我们说,我们有4个表导轨 - 加入4桌

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

的关系是一样的,一对多。假设我们已经知道Ad.id,并且我们想从该Ad.id获取Client.id。

任何人都可以给一个优雅的解决方案(通过优雅的我的意思是没有写入sql语句,而是使用活动记录程序)?

+3

client_id = ad.adgroup.campaign.client.client_id? – Bjoernsen

回答

2

确保Ad belongs_to是一个Adgroup,并在它的db结构中引用它!一直以来,广告组都应该有belongs_to广告系列等等。请记住,与belongs_to的伙计是需要在他的db表中为他的那个人提供参考的人,而不是相反!

如果创建的资源可以开始,那么您应该能够拨打@ad.adgroup.campaign.client.id并获取特定广告(例如获得@ad = Ad.find(some_id))id。

希望这会有所帮助!

+0

是的,这也是最初想到的,但我在某个地方读到这不是一个好习惯。它运行缓慢,吃资源。我正在为解决方案与:连接参数,但不知道如何在没有查询的轨道中做到这一点。 – hudarsono

+0

好吧,据我所知,因为你在模型中创建了这种关系,所以rails会在后台执行连接,所以我真的不觉得这个代码有问题。 –

1

使用Rails关联,您必须记住为关系的另一方指定belongs_to,因此广告最有可能是has_one Adgroup等等等等。一旦你结合了这些关联,你就可以使用ActiveRecord从底部开始链接这些模型,直到层次结构的顶部。所以,你会与广告开始,IT连锁,如:

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

综观上述情况,你可以链Adgroup到一个Ad因为关联关系,让你访问到父模型的方法,所有的到Client模型,其中.id是一种方法,您可以调用它。

看看一些协会基础从Rails的位置:

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

0

首先,确保你有你的关系设置如下:

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 

使用连接,如果你想摘下是客户端ID和高效的SQL:

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

如果你想要整个客户端和高效的SQL,那么只需:

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