2012-01-25 3 views
0

Пусть у нас есть 4 таблицыRails - Объединяя 4 таблицы

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

Отношения же, один ко многим. Скажем, мы знаем Ad.id, и хотим получить Client.id из этого Ad.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

Да, это тоже то, что впервые появилось на уме, но я где-то читал, что это не очень хорошая практика. Он работает медленно и питается ресурсами. Я решил использовать решение: joins parameter, но не знаю, как это сделать в рельсах без запроса. – hudarsono

+0

Ну, из того, что я знаю, поскольку вы создаете эти отношения в модели, рельсы все равно будут делать объединения в фоновом режиме, поэтому я действительно не вижу проблемы с этим кодом ... –

1

С Rails-ассоциациями вы должны не указывать belongs_to для другой стороны отношений, поэтому объявление, скорее всего, будет has_one Adgroup и т. Д. И т. Д. Вверх по цепочке. После того, как вы связали ассоциации, вы можете использовать ActiveRecord для цепи методов, чтобы эти модели начинались снизу, поднимаясь вверху иерархии. Таким образом, вы бы начать с объявлением и приковать его любит:

@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 

Использование соединений и срывать, если все, что вы хотите является идентификатором клиента и эффективным 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