我使用RoR与simple_form和cocoon处理这个结构:Node has_many :addresses
每个Address
都有一个布尔:main
字段,它将标记每个节点地址中的一个作为主地址(实际上是用于SNMP监控的地址)。
我有一个嵌套的形式来管理这些地址,但我找不到一个干净的方式来选择主地址。
逻辑上,我应该使用一个单选按钮组,每个地址是一个单选组选项,但是,在一个嵌套的形式,每个单选按钮将属于一个单一的地址,并有一个不同的名称,这意味着它们在不同的组。
我可以将单选按钮输入链接到Node中的虚拟属性,并在回调中将选定的地址' :main
字段设置为true
,但是我如何将每个按钮链接到它的地址(我可以使用地址ID作为按钮值,但新添加的地址还没有ID)。
下面是我的Node表单的简化版本(括号代表单选按钮,括号代表文本输入):
Name : [MyNode1 ]
| Address | Main |
|------------|------|
| [10.0.0.1] | (*) |
| [10.0.0.2] | ( ) |
| [10.0.0.3] | ( ) |
我唯一的其他解决方案是一个JS馈送的选择框(当我在地址列表中更改某些内容时更新的选项),但它肯定比一个简单的无线电组更不干净和合乎逻辑…
编辑一个"可接受的"解决方案是将单选按钮分组在name
属性以外的其他属性上(例如:data-group
属性)。有人知道有什么好的JS/jQuery插件可以做到这一点吗?
我也遇到过类似的问题,一个Title有许多Role对象(一个HMT glue模型,它表示哪个Person对该Title做了什么——作者、编辑、翻译等等)。每个标题都有一个主要人物,通常是作者,但有时是编辑或馆长,就像在百科全书中一样。正如您所看到的,尽管我进行了尝试,我还是无法让Rails在新创建的嵌套模型中使用单选按钮。下面是我最后做的:
嵌套角色部分:
<p>
<%= f.collection_select :name, person_roles, :to_s, :titleize, {:prompt => "Role"}, {:class => 'combo'} %>
<%= f.collection_select :person_id, Person.order(:sort_name), :id, :reverse_name, :prompt => "Person" %>
<%- if ! f.object.new_record? -%>
<%= radio_button_tag 'title[role_id]', f.object.id, (@title.role_id == f.object.id) %>
<%= label_tag :role_id, "Primary", :for => "title_role_id_#{f.object.id}" %>
<%- end -%>
<%- if ! f.object.new_record? -%>
<%= f.link_to_remove "Delete", :class => 'delete' %>
<%- end -%>
在Title模型中:
has_many :roles, :dependent => :destroy
has_many :people, :through => :roles
belongs_to :role #the primary person, like the author or editor
accepts_nested_attributes_for :roles, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => true
after_create :set_primary
def set_primary
self.update_attributes( :role_id => self.roles.first.id ) if self.roles && self.roles.first
end
所以单选按钮甚至不会出现,除非已经保存了嵌套模型。添加一个新的嵌套模型将使您的表单部分缺少单选按钮和删除链接(因为在保存嵌套子模型之前,两者都无法工作)。