Начиная с Rails 5, когда: inverse_of необходимо устанавливать вручную? - PullRequest
0 голосов
/ 09 января 2019

Я читал в разных местах, что при некоторых обстоятельствах это автоматически выводится, но я нашел документацию по этой функции трудной для понимания. Кто-нибудь может пролить свет на принципы? В частности, когда Rails сможет вывести и когда Rails не сможет вывести обратное?

Я бы хотел рассмотреть

  • полиморфные ассоциации
  • одиночное табличное наследование (например, где BundleProduct и IndividualProduct оба наследуются от Product и используют таблицу products)
  • обычный has_one / has_many / принадлежит_ к ассоциациям
  • имеет много сквозных: ассоциации

Некоторый контекст: Я поддерживаю достаточно большое 9-летнее Rails-приложение со множеством таблиц. Я хотел бы получить некоторые рекомендации о том, какие модели требуют добавления inverse_of: вместо того, чтобы менять каждую модель в системе.

Ответы [ 2 ]

0 голосов
/ 09 января 2019

inverse_of широко не поняли. Он существует, поскольку связанные объекты не указывают на одни и те же объекты в памяти по умолчанию.

Если вы не установите запись: inverse_of, ассоциация выполнит свою лучше всего сопоставить себя с правильным обратным. Автоматический обратный Обнаружение работает только для has_many, has_one и own_to ассоциации.
- Документация по Rails API - ActiveRecord :: Ассоциации :: ClassMethods

В случаях, когда у вас есть «нестандартное» наименование, вам, тем не менее, может потребоваться предоставить опцию:

Автоматическое угадывание обратной ассоциации использует эвристический на основе имени класса, поэтому он может не работать для всех ассоциации, особенно с нестандартными названиями. - Документация по Rails API - ActiveRecord :: Ассоциации :: ClassMethods

Например:

class Pet < ApplicationRecord
  belongs_to :owner, class_name: 'User'
end

class User < ApplicationRecord
  has_many :pets
end

Если мы позвоним pet.owner, это может привести к попаданию в базу данных, даже если мы уже загрузили эту запись.

Если мы добавим опцию inverse_of:

class Pet < ApplicationRecord
  belongs_to :owner, class_name: 'User', inverse_of: :pets
end

class User < ApplicationRecord
  has_many :pets, inverse_of: :owner
end

Теперь, если у нас уже есть эта запись owner в памяти, тогда pet.owner будет указывать на тот же owner.

Как правило, нет явной настройки inverse_of, поэтому вы можете установить его для каждого случая, когда вы не уверены. Вы также можете вручную проверить, требуется ли это, посмотрев, создает ли доступ к ассоциации запрос к БД через консоль или используя musta-matchers с набором тестов.

0 голосов
/ 09 января 2019

Точную процедуру вывода можно найти в ActiveRecord :: Reflection :: AssociationReflection # automatic_inverse_of .

Rails пытается обнаружить инверсию для has_many, has_one и belongs_to, которые не имеют параметров и области действия through, foreign_key и имеют стандартные имена (это также описано в официальном руководстве ).

...