但是,网络上有一些严重的资源,他们说使用acceptance_nested_attributes_for通常是一个糟糕的做法(像这样的@L_301_0@).
需要什么更改才能避免accept_nested_attributes_for,并在哪个文件夹中放置附加的类文件(我猜想需要一个额外的类).
我读到virtus是适合的.是对的吗?
这是一个非常基本的例子,仍然使用accepted_nested_attributes_for(找到完整的例子here):
楷模
class Person < ActiveRecord::Base has_many :phones accepts_nested_attributes_for :phones end class Phone < ActiveRecord::Base belongs_to :person end
调节器
class PeopleController < ApplicationController def new @person = Person.new @person.phones.new end def create @person = Person.new(person_params) @person.save redirect_to people_path end def index @people = Person.all end private def person_params params.require(:person).permit(:name,phones_attributes: [ :id,:number ]) end end
查看(people / new.html.erb)
<%= form_for @person,do |f| %> <p> <%= f.label :name %><br /> <%= f.text_field :name %> </p> <%= f.fields_for :phones do |builder| %> <p> <%= builder.label :number %><br /> <%= builder.text_field :number %> </p> <% end %> <%= f.submit %> <% end %>
[编辑]
使用服务对象是一个好主意吗?
解决方法
我先说说你不需要另一个accept_nested_attributes_for的替代方法,但是我会在这篇文章的结尾加以说明.
参考你提供的链接,它没有引用为什么海报认为accept_nested_attributes_for应该被弃用,只是仅仅是状态
in my humble opinion,should be deprecated
考虑如何以单一形式捕获与父节点相关的多个记录时,嵌套属性是一个非常重要的概念,而不仅仅是一个Ruby on Rails的事情,而是用于大多数复杂的Web应用程序,用于从浏览器发送数据回到服务器,无论用于开发网站的语言.
我没有批评你所指的文章.对我来说,只是指出了一些明显的替代方案来填补数据库支持的模型,其中包含许多不一定与业务逻辑相关的代码.所使用的具体示例仅仅是编码风格偏好替代.
当时间是金钱和压力,一行代码将与该示例中显示的22行代码一样,我的偏好在大多数情况下(不是所有情况)都是在模型中使用一行代码(,accept_nested_attributes_for )接受从表单发回的嵌套属性.
要正确回答你的问题是不可能的,因为你没有真正地说明你为什么认为accept_nested_attributes_for不是很好的做法,但最简单的替代方法是提取控制器操作中的params哈希属性,并在事务中单独处理每个记录.
更新 – 后续评论
I think the author of the linked article argues that,following
oop-paradigms,every object should only read and write its own data.
With accepts_nested_attributes_for,one object however changes some
other objects data.
好.让我们清楚一点.
首先,OO模式不建议这样做.课程应谨慎,但允许与其他课程进行互动.事实上,在Ruby中没有任何意义的OO方法,如果是这样的话,那么Ruby中的一切都是一个类,所以没有什么可以和别的对话.想象一下,如果恰好恰好是控制器实例的对象无法与模型或其他控制器进行交互,会发生什么?
With accepts_nested_attributes_for,one object however changes some
other objects data.
这个声明中的几点,因为它是一个复杂的点,我会尽可能简短.
1)模型实例保护数据.在非常复杂的情况下,以任何/大多数其他语言(C,Delphi,VB等)列出了数百个表,三层解决方案的中间层也是如此.在Rails术语中,模型是业务逻辑的一个地方,并且通过在RDBMS中通常由存储过程和视图备份的3层解决方案执行中间层的工作.模型非常正确应该能够相互交流.
2)accepted_nested_attributes_for根本不违反任何OO原则.它只是简化了你需要编写的代码量,如果方法不存在(正如你们发现的那样).如果您接受嵌套在子模型的params哈希中的属性,那么您所做的就是允许子模型以与控制器的操作相同的方式处理该数据.没有绕过业务逻辑,并获得额外的好处.
最后
I can afford to care about elegance of code (more than about time)
我可以向你保证,编写比您需要的更多的代码行并没有什么优雅,并添加了数百行更多的代码从一个宝石,一行代码将为您做的工作.正如其他人所言(包括我)accept_nested_attributes_for并不总是使用适当的ActiveRecord方法,并且通过查看不同的方法来做是一件好事,因为最终你将能够做出更明智的判断,以便何时使用内置在方法和什么时候写自己的.但是,我建议,要充分了解发生了什么(正如你所说的那样),你最好编写自己的代码来处理表单对象并接受嵌套属性的替代方法.这样你就会发现自己更多的理解.
希望你的学习有意义和好运气.
更新2
最终得到你的观点并参考自己的答案,同时考虑到其他人对自己的答案表示的优秀评论,由virtus gem支持的对象是一个完全合理的解决方案,特别是在处理数据必须集.该组合有助于将用户界面逻辑与业务逻辑分开,只要您最终将数据传递到模型,以便不绕过业务逻辑(因为您显示正在完成此操作),那么您有一个很好的解决方案.
只是不排除accept_nested_attributes不合规定.
您也可以从Ryan Bates观看表格对象的railscasts获得一些好处.