Ruby on Rails中的复选框表单基于多对多关系

时间:2013-03-16 17:40:55

标签: ruby-on-rails ruby-on-rails-3

我的Ruby on Rails应用程序有一个DocumentType模型和一个PersonType模型。文档是DocumentType(例如Letter,Postcard)并列出一个或多个People。每个人都被分配一个PersonType来表示他们与文档的关系(发件人,收件人,作者等)。用户只能将People分配给与DocumentType相关的PersonType。

表定义:

create_table "document_types", :force => true do |t|
 t.string   "name" 
end

create_table "document_types_person_types", :id => false, :force => true do |t|
 t.integer "document_type_id"
 t.integer "person_type_id"
end

create_table "person_types", :force => true do |t|
 t.string   "name"
end

模型定义:

class Document < ActiveRecord::Base
 has_many :people, :dependent => :destroy
 belongs_to :document_type
end

class DocumentType < ActiveRecord::Base
 has_many :documents
 has_and_belongs_to_many :person_types
end

class Person < ActiveRecord::Base
belongs_to :document
has_and_belongs_to_many :person_types
end

class PersonType < ActiveRecord::Base
 has_and_belongs_to_many :people
 has_and_belongs_to_many :document_types
end

表格示例:

documents
 id:   1 
 document_type_id: 1
 name: Letter from John Smith  to Jane and Joe Smith

document_types
 id: 1  |  name: letter

document_types_person_types
 document_type_id: 1  |   person_type_id:   1
 document_type_id: 1  |   person_type_id:   2
 document_type_id: 1  |   person_type_id:   4

person_types
 id: 1  |  name: Sender
 id: 2  |  name: Recipient
 id: 3  |  name: Photographer
 id: 4  |  name: Author  

people
 id: 1  |  document_id: 1  |  name: John Smith  |  person_type_id: 1
 id: 2  |  document_id: 1  |  name: Jane Smith  |  person_type_id: 2
 id: 3  |  document_id: 1  |  name: Joe Smith   |  person_type_id: 2

当用户向文档添加Person时,他们将选择Person与Document的关系,并将存储在Person模型(或扩展模型)中。

文档仅显示与该DocumentType相关的PersonType(例如,照片不会有作者,但会有摄影师)。

毕竟......我想要实现的是DocumentTypes的管理界面,表示document_types_person_types表,它显示了所有PersonTypes,并允许我在PersonType适用时选中一个复选框:

EDIT DocumentType Letter
Sender       [x]
Recipient    [x]
Photographer [ ]
Author       [x]

然后,选择的PersonTypes将是向文档添​​加Person时唯一可用的PersonTypes。希望比我的解释尝试更直接可能代表。任何人都可以提供任何指示吗?

编辑: 为了将来参考,根据弗雷德里克的答案,这是有效的

<% for pt in PersonType.find(:all) %>
  <%= check_box_tag "document_type[person_type_ids][]", pt.id, @document_type.person_types.include?(pt)  %>
  <%= pt.name %>
<% end %>

1 个答案:

答案 0 :(得分:2)

使用这样的关联,DocumentType将有一个person_type_ids方法,该方法返回相关人员类型的ID数组。

因此,如果您创建一组复选框,其名称为document_type[person_type_ids][]且其值为每个人类型的ID,则提交的内容是包含已检查人员类型的ID的数组,因此< / p>

document_type.update_attributes params[:document_type]

会更新协会。这里唯一的细微之处在于,如果没有选中复选框,则不会提交任何数组(您无法提交空数组),并且不会清除关联人员类型列表。我通常通过一个隐藏字段来解决这个问题,该字段将值0添加到数组中(因为我知道它永远不会是合法的id)然后从控制器中的数组中删除0。