rails accepted_nested_attribute 和nested_form



我想介绍一个非常有用的rails工具, nested_form它使编写嵌入式表单变得非常容易。

首先,为了保证代码的简洁和干净(dry, rails提供了fields_foraccepted_nested_attributes_for .通过使用这2个工具,可以在一个表单中嵌入多个关连的模型,而不需要修改controller的方法。例如:

2个关联的模型, Company Branch

 ClassCompany < ActiveRecord::Base

       attr_accessible :name,branches_attributes

has_many:braches

accepted_nested_attributes_for:branches

end

 

 

 

class Branch < ActiveRecord::Base

 attr_accessible:name,address,company_id

 belongs_to :company

end

 

我们可以在company_form.html.erb的文件中增加几行,实现在创建或修改company时,修改branch.

 

 <%= form_for @company do |f| >

<%=f.label :name%><br/>

<%=f.text_field:name %><br/>

<%=f.fields_for:branches do |branch| %>

   <%=branch.label :name %><br/>

   <%=branch.text_field :name %><br/>

   <%=branch.label :address %> <br/>

   <%=branch.text_field :address %><br/>

<% end %>

<%=f.submit%>

 <% end %>

 

以上代码可以实现在创建一个公司时,同时设定他的一个分支。

在使用fields_foraccepted_nested_attributes_for时有几个地方必须注意,否则,你将无法实现你的目标。

 首先,你需要在需要嵌套的模型内,添加

accepted_nested_attributes_for :model_names

 model_names是你需要嵌入的模型名(与has_many句中的模型名相同)

 同时,你必须在attr_accessible句中添加model_names_attributes;注意,这里添加的不是模型名,是模型名加上”_attributes”。这是由于fields_for将使表单生成一个名为model_names_attributes的项,并且accepted_nested_attributes_for生成同名的方法。这样你在创建,或改模型时,不用修改controller的方法就可以实现同时创建模型和该嵌入模型关联的模型。

 另一个需要注意的是,在创建模型时,由于新的模型实例中并没有子模型,这将导致fields_for的子表单无法显示出来。其中一个解决办法是修改new的方法,company为例,new的方法可以是这样的:

 defnew

     @company=Company.new

     @company.branches.build

       respond_with @company

 end

这样,就可以解决在创建时,子表单无法显示的问题。

    那么你可能发现了新的问题了,现在company的表单中只能有一个或者固定数量的子表单。但在实际使用中,通常子表单的数量通常是不固定的,需要动态增减的,如何处理呢?

     一种方案是可以先隐藏一个子表单,然后在需要时用javascripts将其复制表单中。这种方法有一些问题。主要是子表单的ID重名的问题。ID重名的问题将在你使用javascript捕捉子表单的事件时发生。如你需要使用jquerydatepickers

     为了解决上面的问题,并使子表单的问题变简单, 建议使用nested_form.

    只需要添加 gem ‘nested_form’到你的Gemfile然后运行 bundle install.你就会有一个nested_form_for帮助方法了。

      nested_form_for使嵌套子表单变得非常简单。首先,你不必修改new的方法,在表单中点击’add’将会增加一个子表单,‘remove’将会移走一个子表单。将表单提交后,被删除的子表单对应的实例将被删除。如果允许删除已保存在数据库中子表单,accepted_nested_attributes_for句中需要增加:allow_destroy=>true的选项。不需要修改controller的方法。

 使用nested_form_for,在表单中添加<%=f.link_to_add ‘add’ %>将实现子表单的动态增加;

 在子表单中添加<%=branch.link_to_remove ‘remove’ %>将实现子表单的动态删除;

 如果需要使用datepicker之类的javascipt应用,点击<%=f.link_to_add 'add' %> 将会产生一个nested:fieldAdded事件,捕捉这个事件,可以实现在新增加的子表单中,实现datepicker功能。需要注意的是,该事件是从<%=f.link_to_add‘add’%>行产生的,不是从子表单中产生的。

  就这样,非常简单就实现了嵌入表单。可以动态的增加,减少。很少的代码,简单, 漂亮。如果需要更多的信息,可以访问nested_from的主页https://github.com/ryanb/nested_form

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值