Rails: возможно ли добавить дополнительный атрибут к ассоциации has_and_belongs_to_many?
Что я имею в виду, если у меня есть две модели, связанные ассоциацией has_and_belongs_to_many, могу ли я хранить другие данные в таблице соединений для каждой ассоциации? То есть дополнительные данные не будут частью одной записи в любой таблице, а вместо соединения между ними.
Мои фактические модели:
class Part < ActiveRecord::Base
has_and_belongs_to_many :assemblies
has_and_belongs_to_many :packages
belongs_to :user
validates :name, :user_id, :presence => true
end
class Package < ActiveRecord::Base
has_and_belongs_to_many :parts
belongs_to :user
end
Итак, дело в том, что каждая часть доступна во многих пакетах, и каждый пакет имеет разные части. Я хочу добавить количество. Это не будет количество каждой части, а каждого пакета каждой части.
Я не могу найти, как это сделать в ActiveRecord. Если бы я не использовал рельсы /activerecord, я бы просто добавил колонку количества в таблицу соединений, которая связывает части с пакетами. Я мог бы, очевидно, внести это изменение в перенос, но как бы получить доступ к значению с помощью ActiveRecord?
Ответы
Ответ 1
Короткий ответ: нет, вы не можете с отношениями HABTM. Он предназначен только для простых отношений много-много.
Вам нужно будет использовать has_many: через отношения. В этом случае вы создадите модель соединения (PartPackage), где вы сможете определить дополнительные атрибуты, которые вам нужны.
class Part < ActiveRecord::Base
has_many :part_packages
has_many :packages, :through => :part_packages
has_and_belongs_to_many :assemblies
belongs_to :user
validates :name, :user_id, :presence => true
end
class PartPackage < ActiveRecord::Base
belongs_to :part
belongs_to :package
end
class Package < ActiveRecord::Base
has_many :part_packages
has_many :parts, :through => :part_packages
belongs_to :user
end
Ответ 2
Существует ключевое различие между has_many :through
и has_and_belongs_to_many
. Руководство Rails объясняет различия между двумя параметрами более подробно, однако, если вы хотите добавить данные, описывающие отношения, используйте has_many :through
, и вы можете получить доступ к модели, которая объединяет эти два.
Это то, что has_many: через выглядит как:
![Credit to the Rails guide.]()
Ответ 3
Собственно, это возможно.
1) Добавьте количественный ключ в таблицу соединений packages_parts
2) Добавьте это в свою модель детали
has_and_belongs_to_many :packages, -> { select("packages.*,
packages_parts.quantity") }
Теперь вы можете сделать part.packages[0].quantity
, например.
Это означает, что Rails запрашивает количественный ключ всякий раз, когда он получает пакеты для определенной части.
(Вы можете сделать то же самое для своей модели пакета, если хотите сделать package.parts.first.quantity, а также - просто поместите это в модель пакета, заменив "пакеты" на "части" )
Дополнительная информация: https://ducktypelabs.com/using-scope-with-associations/