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

Chr*_*yne 5 ruby-on-rails ruby-on-rails-3

我的Ruby on Rails应用程序有一个DocumentType模型和一个PersonType模型.文档是DocumentType(例如Letter,Postcard)并列出一个或多个People.为每个Person分配一个PersonType来表示他们与Document(发件人,收件人,作者等)的关系.仅允许用户将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
Run Code Online (Sandbox Code Playgroud)

型号定义:

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
Run Code Online (Sandbox Code Playgroud)

表格示例:

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
Run Code Online (Sandbox Code Playgroud)

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

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

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

EDIT DocumentType Letter
Sender       [x]
Recipient    [x]
Photographer [ ]
Author       [x]
Run Code Online (Sandbox Code Playgroud)

选择的那些PersonType将是在向文档添加Person时可用的唯一PersonType.希望比我的解释尝试更直接可能代表.任何人都可以提供任何指示吗?

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

<% 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 %>
Run Code Online (Sandbox Code Playgroud)

Fre*_*ung 2

通过这样的关联,DocumentType 将有一个person_type_ids方法返回关联人员类型的 id 数组。

因此,如果您创建一组复选框,其中名称为名称document_type[person_type_ids][],其值为每个人员类型的 id,那么将提交的是一个包含已检查人员类型的 id 的数组,因此

document_type.update_attributes params[:document_type]
Run Code Online (Sandbox Code Playgroud)

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