rails中accepts_nested_attributes_for应用

Model:

class Blog < ActiveRecord::Base
  has_many  :strip_rules
  accepts_nested_attributes_for :strip_rules, allow_destroy: true
end

  

class StripRule < ActiveRecord::Base
  belongs_to :blog
  attr_accessible :rule, :blog_id
end

  

要实现在新建和修改blog时可以添加/删除任意多个strip_rule

 我们用rails中得 accepts_nested_attributes_for实现这个功能。

新建和修改页面调用模板页面_form.html.erb

#form页面主要实现代码
<%= f.fields_for :strip_rules do |strip_rule| %>
    <%= render "strip_rule", :f => strip_rule %>
<% end %>
<p><%= raw link_to_add_fields("增加一条新规则", f, :strip_rules) %></p>
<div class="form-group">
    <%= f.submit '确定', class: 'btn btn-default' %>
</div>

代码中调用子模板页 _strip_rule.html.erb

<p class="fields">
  <%= f.label :rule, "内容" %>
  <%= f.text_field :rule %>
  <%= link_to_remove_fields "remove", f %><br />
</p>

form页面用到得helper方法

module BlogAdminHelper
  def link_to_remove_fields(name, f)
    f.hidden_field(:_destroy) + link_to_function(name, "remove_fields(this)")
  end
  
  def link_to_add_fields(name, f, association)
    new_object = f.object.class.reflect_on_association(association).klass.new
    fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
      render(association.to_s.singularize, :f => builder)
    end
    link_to_function(name, raw("add_fields(this, \"#{association}\", \"#{escape_javascript(fields)}\")"))
  end
end

以及form页中需要用到得js

<script type="text/javascript">
  function remove_fields(link) {
    $(link).prev("input[type=hidden]").val("1");
    $(link).closest(".fields").hide();
  }

  function add_fields(link, association, rule) {
    var new_id = new Date().getTime();
    var regexp = new RegExp("new_" + association, "g");
    $(link).parent().before(rule.replace(regexp, new_id));
  }
</script>

其中遇到最麻烦的问题是增加一条新内容时html解析出很多&quot; ,导致调用js报错。

解决办法:使用rails提供的辅助方法raw,会调用html_safe方法,去掉&quot;

raw("add_fields(this, \"#{association}\", \"#{escape_javascript(fields)}\")")

最终效果

 

posted @ 2014-11-10 18:33  wangyuyu  阅读(1647)  评论(0编辑  收藏  举报