sql – 连接多个表/约束或带有辅助约束的has_one_through

我为这个人为的例子道歉

一个人有一个旅程,但没有直接连接到那个旅程,相反,他们通过他们的房子和办公室连接.

一个人属于一个房子,一个房子有很多人

一个人属于一个办公室,一个办公室有很多人

旅程属于房子,房子有许多旅程

旅程属于办公室,办公室有许多旅程

                         +---------+
       +---Belongs-To---->         <----Belongs-To--+
       |                 |  House  |                |
       |  +-Has-Many-----+         +-----Has-Many-+ |
       |  |              +---------+              | |
       |  |                                       | |
+------+--v+                                     +v-+--------+
|          |                                     |           |
|  Person  |                                     |  Journey  |
|          |                                     |           |
+------+--^+                                     +^-+--------+
       |  |                                       | |
       |  |              +----------+             | |
       |  +-Has-Many-----+          +----Has-Many-+ |
       |                 |  Office  |               |
       +----Belongs-To--->          <---Belongs-To--+
                         +----------+

在这个人为的例子之后,允许以下内容的最佳方法是什么:

person.journey 

或者禁止使用多个表连接查询(使用ruby哈希)或使用带有额外表约束的has_one_through.

我们确实有一个SQL查询但是如果可以的话我们宁愿避免使用原始的sql,但它看起来像这样:

Person
.joins('INNER JOIN journeys
        ON journeys.office_id = person.office_id
        AND journeys.house_id = person.house_id')

最佳答案 对不起,我必须使用答案才能获得更多信息.

这种情况有可能吗?

| Person                      |   | Journey                     |
|----+-----------+------------|   |----+-----------+------------|
| id | office_id | house_id   |   | id | office_id | house_id   |
|----+-----------+------------|   |----+-----------+------------|
| 1  | 1         | 1          |   | 1  | 1         | 1          |
| 2  | 1         | 1          |   | 2  | 1         | 1          |
| 3  | 1         | 1          |   | 3  | 1         | 1          |
| 4  | 1         | 1          |   | 4  | 1         | 1          |

如何在本案数据中找到特定人员的旅程?

如果您考虑person = Person.find(1)并使用person.office_id和person.house_id作为在Journey表中查找的键,您将获取ID 1,2,3和4.不仅仅是一个旅程.

在您的回复之后,这种情况永远不会发生,因为验证过滤器不允许.
因此,需要使用双外键访问Journey表:office_id和house_id.

最好的解决方案是

class Person < ActiveRecord::Base
  belongs_to :office
  belongs_to :house

  has_one :journey, foreign_keys: [:house_id, :office_id]

end

但rails还不支持多个外键.

一种可能的解决方法是为Person类定义实例方法之旅:

class Person < ActiveRecord::Base
  belongs_to :office
  belongs_to :house

  def journey
    Journey.where(office_id: office_id, house_id: house_id).last
  end

end

所以你可以打电话给person.journey.

点赞