更新:在这里回答.
在这里和互联网上,有很多很好的问题和答案,有关如何使nested_form,collection_select,accepts_nested_attributes_for和fields_for一起很好地玩,但是我仍然很困惑.在此先感谢您能为我提供帮助.
There are lots of good questions and answers here and on the interweb about getting nested_form, collection_select, accepts_nested_attributes_for and fields_for to play nicely together, but I'm still stumped. Thanks in advance if you can help me.
目标:生成新的isbn记录.一个isbn可以有很多贡献者.我已成功使用 ryanb nested_form gem 在表单上动态产生新的贡献者字段,按要求.这些字段之一使用Contributor中所有名称记录的collection_select下拉列表.创建新记录时,需要将许多参与者ID写入联接表(contributors_isbns).
Aim: To generate a new isbn record. An isbn can have many contributors. I am successfully using the ryanb nested_form gem to dynamically produce new contributor fields on a form, as required. One of these fields uses a collection_select drop down of all the name records in Contributor. When the new record is created, the many contributor ids need to be written to the join table (contributors_isbns).
我有一些工作要做,但是直到可以将单个贡献者ID保存到isbns表中的新记录这一点上.在将任何数据写入联接表中,我似乎一无所获.
I have got bits of this working, but only to the point where I can save a single contributor ID to the new record in the isbns table. I can't seem to get anywhere in writing any data to the join table.
我有三个模型.贡献者和Isbns有很多对很多的关系,我已经使用has_many:through完成了.一个isbn可以有很多贡献者,而一个贡献者可以有很多isbns.它们通过contributors_isbn加入.
I have three models. Contributors and Isbns have a many to many relationship, which I've done using has_many :through. An isbn can have many contributors, and a contributor can have many isbns. They are joined via contributors_isbn.
isbn.rb
attr_accessible :contributor_id has_many :contributors, :through => :contributors_isbns has_many :contributors_isbns accepts_nested_attributes_for :contributors accepts_nested_attributes_for :contributors_isbnscontributor.rb
contributor.rb
attr_accessible :isbn_id has_many :contributors_isbns has_many :isbns, :through => :contributors_isbns accepts_nested_attributes_for :isbnscontributors_isbn.rb
contributors_isbn.rb
class ContributorsIsbn attr_accessible :isbn_id, :contributor_id belongs_to :isbn belongs_to :contributor accepts_nested_attributes_for :contributors在isbns控制器中:
In the isbns controller:
def new @isbn = Isbn.new @title = "Create new ISBN" 1.times {@isbn.contributors.build} @isbn.contributors_isbns.build.build_contributor end(显然,我无法决定要使用哪种构建方法.)
(obviously I can't make my mind up on which build method to use.)
在isbns new.html.erb视图中:
In the isbns new.html.erb view:
<%= nested_form_for @isbn, :validate => false do |f| %> <h1>Create new ISBN</h1> <%= render 'shared/error_messages', :object => f.object %> <%= render 'fields', :f => f %> <div class="actions"> <%= f.submit "Create" %> </div> <% end %>在_fields部分中,具有非常简单的text_field的版本:
In the _fields partial, a version with a very plain text_field:
<%= field_set_tag 'Contributor' do %> <%= f.link_to_add "Add Additional Contributor", :contributors %> <li> <%= f.label 'Contributor Sequence Number' %> <%= f.text_field :descriptivedetail_contributor_sequencenumber%> </li> <%= f.fields_for :contributors_isbns, :validate => false do |contrib| %> <li> <%= contrib.label :id, 'contributors_isbns id' %> <%= contrib.text_field :id %> </li> <% end %> <li> <%= f.label 'Contributor Role' %> <%= f.text_field :descriptivedetail_contributor_contributorrole %> </li> <% end %>在这里,这是一个也不起作用的高级版本:
And here, a fancier version which doesn't work either:
<%= f.fields_for :contributors_isbns, :validate => false do |contributors| %> <li> <%= f.label :personnameinverted, 'Contributor Name' %> <%= f.collection_select(:contributor_id, Contributor.all, :id, :personnameinverted ) %> </li> <% end %>此代码使用了此处的答案.两者均在nested_form_for @isbn行上导致缺少块"错误.
This code uses the answer from here. Both result in a 'Missing block" error on the nested_form_for @isbn line.
再次非常感谢.
更新:此处是有关nested_form宝石的一些信息,可能会派上用场看这种问题.这是accepts_nested_attributes_for上的[2009但仍然相关的文章] [4].
Update: here is some info about the nested_form gem which might come in handy for looking at this sort of problem. And here's a [2009 but still relevant post][4] on accepts_nested_attributes_for.
更新2:好吧,这是一件事情.我一直在两个不同的模型中使用它的简化版本,而不是通过collection_select或has_many来使用,而只是在一个简单的Emirates_to/has_many关联上.父模型是Contract,子模型是Istc.我什至无法通过嵌套表单创建记录.但是,在查看堆栈并搜索错误消息警告.无法批量分配受保护的属性"之后,我刚刚在:attr_accessible行中添加了:istcs_attributes,现在可以添加记录了.相当重要的一点缺失,以及RTFM的情况,因为它在gem自述文件中就存在.稍后我将进行更新,以查看是否可以通过关联在更复杂的has_many上使用.
Update 2: well, here's a thing. I've been poking around on a cut-down version of this in two different models, not using collection_select or has_many through, but just on a simple belongs_to / has_many association. The parent model is Contract and the child model is Istc. I couldn't even create a record through the nested form. However, after looking in the stack and googling the error message "Warning. Can't mass-assign protected attributes" I've just added :istcs_attributes to my :attr_accessible line and now I can add records. A rather crucial bit missing, and a case of RTFM, as it's right there in the gem readme. I'll update later to see if this works on the more complicated has_many through association.
更新4:[此处] [5]是有关如何处理nil记录错误消息的另一篇有用的文章.
Update 4: [Here][5] is another useful post about how to deal with a nil record error message.
更新5:略微绕行-当我向表单中动态添加一组新字段时,正在创建一个子记录. h-我在子表单区域内拥有添加"链接.之前是这样:
Update 5: Slight detour - When I dynamically added a new set of fields to the form, one one of the child records was being created. Duh - I had the "Add" link inside the child forms area. Here's the before:
<%= f.fields_for :istcs do |istc_form| %> <h4> Istc</h4> <%= istc_form.label "istc name" %> <%= istc_form.text_field :title_title_text %> <%= istc_form.link_to_remove "[-] Remove this istc"%> <%= f.link_to_add "[+] Add an istc", :istcs %> <% end %>以下是:
<%= f.fields_for :istcs do |istc_form| %> <h4> Istc</h4> <%= istc_form.label "istc name" %> <%= istc_form.text_field :title_title_text %> <%= istc_form.link_to_remove "[-] Remove this istc"%> <% end %> <%= f.link_to_add "[+] Add an istc", :istcs %>更新6,答案后:
哦,是的. collection_select无法正常工作.它正在添加新的参与者记录,而不使用参与者模型中的现有记录. 其他人也遇到了这个问题.有任何想法吗?
Oh noes. The collection_select isn't working. It's adding new contributor records, not using an existing one from the contributor model. Someone else had this problem too. Any ideas?
推荐答案Huzzah!这是使所有这些工作有效的代码.有点冗长,但不想遗漏任何内容.我的主要学习成果:
Huzzah! Here's the code which makes all this work. Bit verbose but didn't want to leave anything out. My main learnings:
-
您需要在父模型中使子属性attr_accessible
you need to make the child attributes attr_accessible in the parent model
您需要在联接表模型中使父ID和子ID attr_access可访问
you need to make the parent and child ids attr_accessible in the join table model
如果您在父控制器中构建至少一个子实例,将使生活变得更轻松.
it makes life easier if you build at least one child instance in the parent controller.
contributor.rb模型
contributor.rb model
class Contributor < ActiveRecord::Base attr_accessible #nothing relevant has_many :contributors_isbns has_many :isbns, :through => :contributors_isbnsisbn.rb模型
class Isbn < ActiveRecord::Base attr_accessible :contributors_attributes, :contributor_id, :istc_id #etc belongs_to :istc has_many :contributors, :through => :contributors_isbns has_many :contributors_isbns accepts_nested_attributes_for :contributors #if you omit this you get a missing block errorcontributors_isbn模型
contributors_isbn model
class ContributorsIsbn < ActiveRecord::Base belongs_to :isbn belongs_to :contributor attr_accessible :isbn_id, :contributor_idisbn控制器
def new @isbn = Isbn.new @title = "Create new ISBN" 1.times {@isbn.contributors.build} endnew.html.erb
new.html.erb
<td class="main"> <%= nested_form_for @isbn, :validate => false do |f| %> <h1>Create new ISBN</h1> <%= render 'shared/error_messages', :object => f.object %> <%= render 'fields', :f => f %> <div class="actions"> <%= f.submit "Create" %> </div> <% end %>_fields.html.erb
_fields.html.erb
<%= field_set_tag 'Identifier Details' do %> <li> <%= f.label 'Title prefix' %> <%= f.text_field :descriptivedetail_titledetail_titleelement_titleprefix %> </li> <li> <%= f.label 'Title without prefix' %> <%= f.text_field :descriptivedetail_titledetail_titleelement_titlewithoutprefix %> </li> <li> <%= f.label 'ISTC' %> <%= f.collection_select(:istc_id, Istc.all, :id, :title_title_text, :prompt => true) %> </li> <% end %> <%= field_set_tag 'Contributor' do %> <li> <%= f.label 'Contributor Sequence Number' %> <%= f.text_field :descriptivedetail_contributor_sequencenumber%> </li> <%= f.fields_for :contributors, :validate => false do |contributor_form| %> <li> <%= contributor_form.label :personnameinverted, 'Contributor Name' %> <%= contributor_form.collection_select(:isbn_id, Contributor.all, :id, :personnameinverted ) %> </li> <%= contributor_form.link_to_remove "[-] Remove this contributor"%> <% end %> <%= f.link_to_add "[+] Add a contributor", :contributors %> <li> <%= f.label 'Contributor Role' %> <%= f.text_field :descriptivedetail_contributor_contributorrole %> </li> <% end %>更多推荐
Rails 3:nested
发布评论