首页 > 解决方案 > Ruby on Rails:两个模型都有 Has/Many 和 Belongs_to

问题描述

我最近继承了一个旧的 rails 应用程序,它有一个名为Package. 其中一项任务是能够允许删除包。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

重组的最佳方式是什么

标签: mysqlruby-on-railsrubydatabase

解决方案


您所描述的是 and 之间的单向has_and_belong_to_many ( HABTM) 关联,如下所示:PackagePackageState

class Package < ActiveRecord::Base
  has_and_belongs_to_many :package_states
end

class PackageState < ActiveRecord::Base
  has_many :packages
end

这个SO question的公认答案有以下关于单向 HABTM 关联的摘录:

功能上是,但语义上不是。以“片面”的方式使用 HABTM 将完全实现您想要的。不幸的是,HABTM 这个名字确实暗示了一种并非总是如此的互惠关系。同样,belongs_to :foo 在这里也没有什么直观意义。

不要陷入 HABTM 和其他关联的语义中,而只需考虑您的 ID 需要放在哪里,以便适当且有效地查询数据。请记住,效率考虑首先应考虑您的生产力。

你还说

PackageState由于和Package模型的设置方式,这目前是不可能的

但这是不正确的。没有什么能阻止您使用ActiveRecord和调用destroy它来获取包对象。

您应该问自己打算如何使用这两种模型(尤其是在删除包时)并确定哪种关联效果最好。考虑到这是一个继承的应用程序,您可能需要处理遗留数据,但这是另一天的话题。


推荐阅读