Недавно я унаследовал старое приложение rails, которое имеет модель под названием Package
. Одна из задач - разрешить удаление пакетов. Однако это невозможно в настоящее время из-за того, как PackageState
модели PackageState
и Package
. Вот пример:
Модель упаковки:
class Package < ActiveRecord::Base
belongs_to :package_state, class_name: 'PackageState', foreign_key: :package_state_id
has_many :package_states
end
И PackageState:
class PackageState < ActiveRecord::Base
has_many :packages, :class_name => 'Package'
end
Каким будет лучший способ реорганизации
То, что вы описываете, является односторонней связью has_and_belong_to_many (HABTM) между Package
и PackageState
, которая будет выглядеть так:
class Package < ActiveRecord::Base
has_and_belongs_to_many :package_states
end
class PackageState < ActiveRecord::Base
has_many :packages
end
Принятый ответ из этого вопроса SO имеет эту выдержку об односторонних ассоциациях HABTM:
Функционально да, но семантически нет. Использование HABTM в одностороннем режиме позволит достичь именно того, что вы хотите. Имя HABTM, к сожалению, намекает на взаимные отношения, что не всегда так. Аналогично, belongs_to: foo здесь мало интуитивно понятен.
Не увлекайтесь семантикой HABTM и другой ассоциации, вместо этого просто учитывайте, где ваши идентификаторы должны сидеть, чтобы правильно и эффективно запрашивать данные. Помните, что соображения эффективности должны прежде всего учитывать вашу производительность.
Вы также заявили, что
что в настоящее время невозможно, из-за того, как
PackageState
моделиPackageState
иPackage
но это не совсем правильно. Ничто не мешает вам получить объект пакета с помощью ActiveRecord
и вызвать его destroy
.
Вы должны спросить себя, как вы собираетесь использовать обе модели (особенно когда дело доходит до удаления пакетов) и определить, какая ассоциация будет работать лучше всего. Учитывая, что это унаследованное приложение, вам, скорее всего, придется иметь дело с устаревшими данными, но это тема для другого дня.