Объединяет с несколькими таблицами / ограничениями ИЛИ has_one_through со вторичным ограничением - PullRequest
0 голосов
/ 06 июля 2018

Я прошу прощения за надуманный пример

A person имеет ОДИН journey, но напрямую не связан с этим journey, вместо этого они подключены через свои house и office.

A person belongs_to a house, house has_many people

A person belongs_to a office, office has_many people

A journey belongs_to a house, house has many journeys

A journey belongs_to a office, a office has many journeys

                         +---------+
       +---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-запрос, но мы бы предпочли не использовать raw SQL, если можем, но он выглядит так:

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

1 Ответ

0 голосов
/ 08 июля 2018

Извините, я должен использовать ответ, чтобы получить больше информации. Возможно ли иметь этот случай?

| 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 в качестве ключей для поиска в таблице Путешествие, вы получите идентификаторы 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

но несколько внешних ключей еще не поддерживаются рельсами.

Одним из возможных обходных путей может быть определение метода экземпляра journey для класса 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.

...