2013-04-20 12 views
22

W Ruby on Rails chcę znaleźć pracodawców w mieście. Powiedzmy modele są ustawione w ten sposób:Szyny łączą się poprzez asocjację

City 
has_many :suburbs 
has_many :households, :through => suburbs 
has_many :people, :through => suburbs 

Suburb 
has_many :households 
has_many people, :through => households 
belongs_to :city 


Household 
has_many :people 
belongs_to :suburb 

People 
belongs_to :household 
belongs_to :employer 


Employer 
has_many :people 

czuję się jak chcę jakiś pracodawca dołącza some_city.people ale nie wiem jak to zrobić. Gdyby ludzie należeli bezpośrednio do miast, mógłbym przyłączyć się do Pracodawcy do osób, gdzie city_id jest czymś, ale chcę znaleźć te same dane bez bezpośredniego łączenia się i jestem trochę zagubiony.

Dziękuję.

+0

Czy starasz się zrobić to w szynach? Dlaczego po prostu nie skorzystać z ich metod pomocniczych? – Steve

+0

Przykro mi, którą metodę pomocnika poleciłbyś do tego? – spitfire109

+0

Dlaczego nie przechodzisz relacji przez 'has_many: through' z' Employer', tak jak robisz z 'City'? –

Odpowiedz

15

Możesz zrobić to dołączyć jak jvans został zilustrowany. Lub można skonfigurować swoje relacje tak:

class Employer < ActiveRecord::Base 
    has_many :people 
    has_many :households, through: :people 
    has_many :suburbs, through: :households 
    has_many :cities, through: :suburbs 
end 

class Person < ActiveRecord::Base 
    belongs_to :household 
    belongs_to :employer 
end 


class Household < ActiveRecord::Base 
    belongs_to :suburb 
    has_many :people 
end 

class Suburb < ActiveRecord::Base 
    belongs_to :city 
    has_many :households 
    has_many :people, through: :households 
end 

class City < ActiveRecord::Base 
    has_many :suburbs 
    has_many :households, through: :suburbs 
    has_many :people, through: :households 
    has_many :employers, through: :people 
end 

Następnie można przystąpić City z Employer i vice versa, bezpośrednio.

Na przykład:

Employer.joins(:cities).where("cities.name = ?", "Houston").first 

SELECT "employers".* FROM "employers" 
INNER JOIN "people" ON "people"."employer_id" = "employers"."id" 
INNER JOIN "households" ON "households"."id" = "people"."household_id" 
INNER JOIN "suburbs" ON "suburbs"."id" = "households"."suburb_id" 
INNER JOIN "cities" ON "cities"."id" = "suburbs"."city_id" WHERE (cities.name = 'Houston') 
LIMIT 1 
+0

Wow. Byłem całkowicie nieświadomy, że mógłbym stworzyć takie stowarzyszenie. idę wdrożyć to, Podejrzewam, że jest to właśnie odpowiedź, której szukam do opracowania przyszłych podobnych zapytań. – spitfire109

+0

Tak, począwszy od Rails 3.1, zagnieżdżone relacje 'has_many: through' działają całkiem nieźle. –

31

Użyj zagnieżdżone dołącza

Employer.joins({:people => {:household => {:suburb => :city}}}) 

powinno dać tabelę dołączyć którego szukasz. Jeśli były przejeżdżające w innym kierunku należałoby użyć liczby mnogiej nazw

City.joins(:suburbs => {:households => {:people => :employers }}) 
+0

Okay Myślę, że o to właśnie pytałem. Aby wyjaśnić składnię, w jaki sposób ostateczne skojarzenie miałoby na celu identyfikację konkretnego miasta? Powiedzmy, że chcę znaleźć wszystkich pracodawców, którzy zatrudniają ludzi z Chicago, który ma identyfikator modelu 1? – spitfire109

+1

Dodaj do tego klauzulę where (gdzie "pracers.city IN? I employerers.id in?", Miasto, id) – jvans

+1

Również piszę klejnot o nazwie searchlogic, aby działał z aktywnym rekordem 3 i powinien zostać zrobiony wkrótce. To sprawia, że ​​takie wyszukiwania w twojej aplikacji są dość banalne. Https://github.com/binarylogic/searchlogic?source=cr – jvans

Powiązane problemy