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)
通过这样的关联,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。