Rails: возможно ли добавить дополнительный атрибут в ассоциацию has_and_belongs_to_many? - PullRequest
19 голосов
/ 23 февраля 2012

Что я имею в виду, если у меня есть две модели, связанные ассоциацией 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. Если бы я не использовал rails / activerecord, я бы просто добавил столбец количества в таблицу соединений, который связывает детали с пакетами. Я мог бы внести это изменение в миграцию, но как мне получить доступ к значению с помощью ActiveRecord?

Ответы [ 3 ]

28 голосов
/ 23 февраля 2012

Короткий ответ: нет, вы не можете иметь отношения с HABTM.Он предназначен только для простых отношений «многие ко многим».

Вам нужно будет использовать отношение has_many: through.В этом сценарии вы создадите модель соединения (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
14 голосов
/ 23 февраля 2012

Существует ключевое различие между has_many :through и has_and_belongs_to_many. Руководство по Rails объясняет различия между двумя вариантами более подробно, однако, если вы хотите добавить данные, которые описывает отношения, затем используйте has_many :through, и вы можете получить доступ к модели, которая объединяет эти два.

Вот как выглядит has_many: through: Credit to the Rails guide.

2 голосов
/ 17 мая 2017

На самом деле это возможно.

1) Добавить количественный ключ в таблицу присоединения к packages_parts

2) Добавьте это к своей модели детали

has_and_belongs_to_many :packages, -> { select("packages.*, 
packages_parts.quantity") }

Теперь вы можете сделать part.packages[0].quantity, например.

Что это делает, так это заставляет Rails извлекать ключ количества всякий раз, когда он получает пакеты для определенной части.

(Вы можете сделать то же самое для вашей модели Package, если вы хотите сделать также package.parts.first.quantity - просто поместите это и в модель Package, заменив 'packages' на 'parts')

Дополнительная информация: https://ducktypelabs.com/using-scope-with-associations/

...