5

我的 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 添加到 Document 时,他们将选择 Person 与 Document 的关系,并将其存储在 Person 模型(或扩展模型)中。

Document 只会显示与该 DocumentType 相关的 PersonType(例如,Photo 不会有 Author,但会有摄影师)。

所以毕竟......我想要实现的是 DocumentTypes 的管理界面,代表 document_types_person_types 表,该表显示所有 PersonTypes 并允许我选择一个复选框(如果 PersonType 适用):

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

然后,在将人员添加到文档时,选择的那些 PersonTypes 将是唯一可用的 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 %>
4

1 回答 1

2

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

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

document_type.update_attributes params[:document_type]

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

于 2013-03-16T17:48:15.820 回答