Подтвердить что ты не робот

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?

4b9b3361

Ответ 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/