HABTM和accepts_nested_attributes_for

Mar*_*jan 9 ruby-on-rails ruby-on-rails-3

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

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

我还想对作者表单做同样的事情:添加书名和提交,如果它们存在则链接它们,或者如果它们不存在则创建它们.

但是,在编辑时,我希望既不能编辑也不能删除嵌套对象,只能删除关联.

accepted_nested_attributes_for适合这个,还是有另一种方式?

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

tad*_*man 12

我不确定为什么这么多人使用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
Run Code Online (Sandbox Code Playgroud)

您现在可以更轻松地链接每个其他模型:

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
Run Code Online (Sandbox Code Playgroud)

在嵌套表单上,book_authors直接管理关系,根据需要添加和删除关系.

  • 人们使用HABTM over_many:through的原因是因为不是每个多对多连接表都需要一个模型来管理它.复杂数据模型有很多连接表,除了表达两个其他表之间的关系之外什么都不做,这种情况并不少见. (36认同)
  • 该方法的名称与其是否存在无关.使用任何数量的不执行任何操作的模型/类来对代码库进行污染是一种代码气味,应该不惜一切代价避免,即使有"你很可能"需要它们.如果您需要它们,只需在需要时进行更改. (8认同)
  • 显然,有一个地方HABTM.从3.2.3文档:"选择构建多对多关系的方式并不总是很简单.如果您需要将关系模型作为自己的实体使用,请使用has_many:through.使用has_and_belongs_to_many处理遗留问题时模式或当你从不直接与关系工作时".对我来说似乎足够合理. (8认同)
  • 老实说,我不能不同意.`has_and_belongs_to_many`是一个笨重的古代,在现代的Rails应用程序中没有地位.连接模型即使很简单,也可以用于特定目的:定义两个实体之间的关系.在ActiveRecord中没有模型的表不是随便做的事. (2认同)