【问题标题】:HABTM and accepts_nested_attributes_forHABTM 和 accept_nested_attributes_for
【发布时间】:2011-02-07 17:09:26
【问题描述】:

假设我有两个模型,Book 和 Author,它们之间具有 has_and_belongs_to_many 关系。

我想要做的是能够在书籍表单中添加作者姓名,并在提交时将作者与书籍链接(如果它们已经存在),或者如果它们不存在则创建它们。

我也想对作者表单做同样的事情:添加书名并在提交时链接它们(如果它们存在),或者创建它们(如果它们不存在)。

然而,在编辑时,我既不想编辑也不想删除嵌套对象,只删除关联。

accepts_nested_attributes_for 适合这个,还是有其他方法?

我设法通过遵循 Rails 2 上的 Complex Forms railscasts 来实现这一点,但我正在为 Rails 3 寻找更优雅的解决方案。

【问题讨论】:

标签: ruby-on-rails ruby-on-rails-3


【解决方案1】:

我不知道为什么这么多人使用 has_and_belongs_to_many,它是 Rails 1 的遗物,而不是使用 has_many ..., :through,除非它可能在很多旧的参考书和教程中。这两种方法的最大区别在于第一种使用复合键来识别它们,第二种使用一流的模型。

如果您重新定义您的关系,您可以在中间模型级别进行管理。例如,您可以添加和删除 BookAuthor 记录,而不是 has_and_belongs_to_many 链接,众所周知,这些链接很难单独调整。

您可以创建一个简单的模型:

class BookAuthor < ActiveRecord::Base
  belongs_to :book
  belongs_to :author
end

您的每个其他模型现在更容易链接:

class Book < ActiveRecord::Base
  has_many :book_authors
  has_many :authors, :through => :book_authors
end

class Author < ActiveRecord::Base
  has_many :book_authors
  has_many :books, :through => :book_authors
end

在您的嵌套表单上,直接管理 book_authors 关系,并根据需要添加和删除这些关系。

【讨论】:

  • 人们使用 HABTM 而不是 has_many :through 的原因是不是每个多对多连接表都需要模型来管理它。对于一个复杂的数据模型来说,有很多只表达其他两个表之间关系的连接表并不罕见。
  • 方法的名称与它是否应该存在无关。用任何数量的模型/类来污染代码库是一种代码异味,应该不惜一切代价避免,即使“你有一点机会”需要它们。如果您需要它们,只需在需要时进行更改。
  • 老实说,我不能再不同意了。 has_and_belongs_to_many 是一个笨重的古老事物,在现代 Rails 应用程序中没有位置。连接模型即使很简单,也有一个特定的目的:定义两个实体之间的关系。 ActiveRecord中没有模型的表不是随便做的。
  • 显然,HABTM 有一个地方。来自 3.2.3 文档:“选择建立多对多关系的方式并不总是那么简单。如果您需要将关系模型作为其自己的实体使用,请使用 has_many :through。使用遗留时使用 has_and_belongs_to_many模式或当您从不直接处理关系时”。对我来说似乎足够合理。
  • 之前好像在 SO 上讨论过这个问题:stackoverflow.com/questions/658206/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-20
  • 2011-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多