Oh!Coder

Coding Life

Cocoon Gem 简介

| Comments

最近工作中接触到一个Gem,名字叫Cocoon。为了有一个积累,在此简单做一个记录,:)

功能简介

Cocoon的主要作用是用来实现Rails中view层的form多层嵌套功能。Cocoon的使用,可以在标准的Rails中单独使用,也可以结合FormtasticSimpleForm使用。

注意事项

Cocoon的实现,本质上封装了一段javascript的程序,所以在使用的过程中,依赖于jQuery的代码库,在添加好Gem之后,需要在application.js文件中加入一行代码,以此引入Cocoon的javascript文件。

1
//= require cocoon

基本使用

这里列举一个文档中的例子,以示简单说明。

假设有一个Projectmodel:

1
rails g scaffold Project name:string description:string

这个Project有多个task:

1
rails g model Task description:string done:boolean project:belongs_to

这两个model的关系如下:

1
2
3
4
5
6
7
8
class Project < ActiveRecord::Base
    has_many :tasks
    accepts_nested_attributes_for :tasks, :reject_if => :all_blank, :allow_destroy => true //这行代码必须要有,详情可参见Rails文档
end

class Task < ActiveRecord::Base
    belongs_to :project
end

对于删除嵌套model,rails使用一个名叫_destroy的虚拟attribute。当设置了_destroy之后,嵌套的model可以被自动级联删除。另外,rails会根据id字段来对记录进行添加和删除操作。如果记录已经存在,rails可以根据id字段进行查找并进行删除,如果没有指定id,rails会将当前的parameter看作一条新的记录。

所以在controller层使用strong parameter特性时,需要添加:id:_destroy两个字段。举例如下:

ProjectsController中:

1
2
3
def project_params
    params.require(:project).permit(:name, :description, tasks_attributes: [:id, :description, :done, :_destroy])
end

对于View层实现来说,简单示例如下:

首先在projects文件夹下创建一个_form.html.erb文件

1
2
3
4
5
6
7
8
9
10
11
<%= form_for(@project) do |f| %>
  <div class="parent-menus">
    <%= f.fields_for :tasks do |task| %>
    <%= render 'task_fields', :f => task %>
    <% end %>
    <%= link_to_add_association 'add task', f, :tasks %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

注意:这里的div必须要有,否则提交的表单中丢失所填写的字段信息。

然后在projects文件夹下创建另一个文件,名叫_task_fields.html.erb

1
2
3
4
5
6
7
<div class="nested-fields">
  <%= f.label :description %>
  <%= f.text_field :description %>
  <%= f.check_box :done %>
  <%= f.label :done %>
  <%= link_to_remove_association "remove task", f %>
</div>

注意:这里的div必须要有,否则最终无法实现删除功能。

辅助方法

此Gem主要提供了两个辅助方法:

1
link_to_add_association

1
link_to_remove_association

这两个辅助方法可以传入一些不同的参数,以此可以达到不同的使用效果。具体使用详情可以参见Github上的使用文档,在此就不赘述了。

Comments