Rails 通过关联加入

Posted

技术标签:

【中文标题】Rails 通过关联加入【英文标题】:Rails joins through association 【发布时间】:2013-04-13 12:05:18 【问题描述】:

在 Ruby on Rails 中,我想在城市中寻找雇主。 假设模型是这样设置的:

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

我觉得我想要某种雇主加入 some_city.people,但我不知道该怎么做。如果人们直接属于城市,我可以将 Employer 加入到 city_id 的人,但我想在没有直接加入的情况下找到相同的数据,我有点迷茫。

谢谢。

【问题讨论】:

您是否尝试在 Rails 中执行此操作?为什么不直接使用他们的辅助方法? 很抱歉,您会为此推荐哪种辅助方法? 你为什么不通过has_many :throughEmployer 遍历关系,就像你从City 做的那样? Nvm,不知道最好的方法是什么,sry 一个雇主可以是多个城市,所以它不一定只属于一个城市。我可以创建一个连接表,但这似乎需要做很多事情。我可以给人们一个 city_id,但这似乎不是标准化的方法,因为该信息应该可以通过当前记录获得。 【参考方案1】:

使用嵌套连接

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

应该给你你正在寻找的连接表。如果您要穿越另一个方向,您将使用复数名称

City.joins( :suburbs => :households => :people => :employers )

【讨论】:

好的,我想这就是我要问的。只是为了澄清语法,如何建立最终关联来识别特定城市?假设我想查找所有雇用芝加哥员工的雇主,其模型 ID 为 1? 向其中添加 where 子句 .where("employers.city IN ? AND employees.id in ?, city, id) 另外,我正在重写一个名为 searchlogic 的 gem 来处理活动记录 3,应该很快就会完成。它使在您的应用程序中进行这样的搜索变得非常简单。 github.com/binarylogic/searchlogic?source=cr 感谢您的帮助。我选择了另一个答案,但从所有回复中学到了很多。我会留意搜索逻辑,干得好。 @BKSpureon 添加 where 子句。 Employer.joins(:people => :household => :suburb => :city) .where("cities.name = 'Houston'")【参考方案2】:

您可以像 jvans 所示的那样进行连接。或者你可以像下面这样设置你的关系:

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

然后您可以直接从Employer 加入City,反之亦然。

例如:

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

【讨论】:

哇。我完全不知道我能做出那种联想。让我去实现它,我怀疑这正是我正在寻找的解决未来类似查询和东西的答案。 是的,从 Rails 3.1 开始,嵌套的 has_many :through 关系运行良好。

以上是关于Rails 通过关联加入的主要内容,如果未能解决你的问题,请参考以下文章

复杂的 Rails 模型/关联

带有has_many的模型中的属性总和:通过关联在Rails 5中不起作用

同一张表的多个关联(多对多)Ruby on Rails

Rails:使用 where 子句查找深度嵌套的关联

为啥 Rails 在通过关联创建新记录时不更新其关联缓存?

通过深度关联访问 rails 属性