nested_form,collection_select,accepts_nested_attributes_for和fields_for,并将记录添加到联接表 [英] nested_form, collection_select, accepts_nested_attributes_for and fields_for, and adding records to a join table

查看:45
本文介绍了nested_form,collection_select,accepts_nested_attributes_for和fields_for,并将记录添加到联接表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:根据此问题结尾处发布的堆栈跟踪,我认为真正的问题是弄清楚什么attr_accessible并建立关联设置,我需要获取贡献者和链接器属性以使用新的ISBN ID.请帮帮我!

接着是此问题...

我在两个模型(isbns和贡献者)之间有一个联接表,它们之间具有多对多的关系.我想在使用fields_for的嵌套表单中的collection_select下拉列表中使用贡献者模型中的现有值.

I've got a join table between two models - isbns and contributors - which have a many to many relationship. I want to use the existing values from the contributor model in a collection_select drop-down, within a nested form using fields_for.

因此,当我创建一个新的isbn时,我不想创建新的参与者记录-我希望能够选择现有的记录.而且我希望能够选择许多贡献者,这就是为什么我使用

So when I'm creating a new isbn, I don't want to create new contributor records - I want to be able to select existing ones. And I want to be able to select many contributors, which is why I'm using the nested_form gem which allows me to dynamically create additional form fields for contributors.

我的问题:我应该在联接表上调用该方法吗?如果是这样,尽管拥有attr_accessible和accepts_nested_attributes_for的几乎所有内容,我为什么仍会收到缺少块"错误:

My question: should I be calling the method on the join table? And if so, why do I get a 'missing block' error despite having pretty much everything attr_accessible and accepts_nested_attributes_for:

isbn.rb:

  attr_accessible :linkers_attributes, :contributors_attributes, :contributor_id,
  has_many   :linkers
  has_many   :contributors, :through => :linkers
  accepts_nested_attributes_for :contributors
  accepts_nested_attributes_for :linkers

contributor.rb:

contributor.rb:

attr_accessible :linkers_attributes, :isbns_attributes 
  has_many :linkers
  has_many :isbns, :through => :linkers
  accepts_nested_attributes_for :isbns
  accepts_nested_attributes_for :linkers

linker.rb:

linker.rb:

belongs_to :isbn
  belongs_to :contributor
  accepts_nested_attributes_for :contributor
  accepts_nested_attributes_for :isbn
  attr_accessible :isbn_id, :contributor_id, :isbns_attributes, :contributors_attributes, :contributor_attributes, :isbn_attributes

isbns控制器:

def new
    @isbn  = Isbn.new
    @title = "Create new ISBN"
    1.times {@isbn.linkers.build}
  end

new.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>  

_fields :(选项1)

_fields: (option 1)

<%= f.fields_for :contributors do |contributor_form| %>
<li>
<%= contributor_form.label '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  %>

当我实际上希望新的链接器记录包含现有的contributor_id时,这将创建一个新的ISBN,并在链接器中使用正确的isbn_id记录一个新记录,同时也在贡献者中创建一个新记录.所以我想我会这样做:

This creates a new ISBN, and a new record in linkers with the correct isbn_id, but also a new record in contributors, when I actually want the new linker record to contain an existing contributor_id. So I figured I'd do this:

_fields(选项2)

_fields (option 2)

<%= field_set_tag 'Contributor' do %>
<li>
<%= f.label 'Contributor Sequence Number' %>
<%= f.text_field :descriptivedetail_contributor_sequencenumber%>
<%= tooltip(:xxx, :hover) %>
</li>

<%= f.fields_for :linkers do |contributor_form| %>
<li>
<%= contributor_form.label '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  %>

但是这将返回缺少的块错误.

But this returns a missing block error.

在此先感谢您,我花了整整两天的时间,认为自己可能会流行.

Huge thanks in advance, I've spent two solid days on this and think I might pop.

更新:这是一个线索,来自此新代码的堆栈跟踪,因为我认为您实际上无法在联接表上调用方法:

update: Here's a clue, the stack trace from this new code, because I figured you can't actually call a method on a join table:

<%= f.fields_for :contributors do |contributor_form| %>
<li>
<%= contributor_form.collection_select(:id, Contributor.all, :id, :personnameinverted, :include_blank => true ) %>



Started POST "/isbns" for 127.0.0.1 at 2011-06-08 20:12:48 +0100
  Processing by IsbnsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"u0TszLESOnZlr4iEiBlVg6w9B5T+EH0dxJg/0E6PKuQ=", "isbn"=>{"descriptivedetail_titledetail_titleelement_titleprefix"=>"", "descriptivedetail_titledetail_titleelement_titlewithoutprefix"=>"qqq", "istc_id"=>"471", "descriptivedetail_contributor_sequencenumber"=>"", "contributors_attributes"=>{"0"=>{"id"=>"1", "_destroy"=>"false"}, "1307560328932"=>{"id"=>"14", "_destroy"=>"false"}}, "descriptivedetail_contributor_contributorrole"=>""}, "commit"=>"Create"}
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 2 LIMIT 1
  Contributor Load (0.3ms)  SELECT "contributors".* FROM "contributors" INNER JOIN "linkers" ON "contributors".id = "linkers".contributor_id WHERE "contributors"."id" IN (1, 14) AND (("linkers".isbn_id = NULL))
Completed   in 308ms

因此,看起来好像实际上已经在设置贡献者ID,但是没有向链接器表传递isbn ID.继续...

So it looks like the contributor IDs are actually being set, but the linker table isn't being passed the isbn id. Onwards...

推荐答案

好.这是我的方法.

已安装茧宝石. 终于也开始安装Haml了,

Installed cocoon gem. Finally got round to installing Haml, too,

我拆分了new和update动作,因此新表单只是获取ID集的快捷方式,几乎没有字段.然后,用户可以对其进行编辑,并添加贡献者.从用户的角度来看,这实际上还不错,因为他们可以快速创建一个isbn,而不必填写大量的字段.

I split out the new and update action, so the new form is just a quickie to get the id set, with the bare minimum of fields. Then users can edit it, and add contributors. Not actually bad from the user point of view as they can create an isbn quickly without having to fill in a bazillion fields.

isbns/new.html.haml

isbns/new.html.haml

%td.main
= semantic_form_for @isbn do |f|
  %h1 Create new ISBN
  = render 'shared/error_messages', :object => f.object
  = render 'fields', :f => f
  %div#actions
  = f.submit "Create"

isbns/_fields.html.haml

isbns/_fields.html.haml

- f.inputs do
  = f.input :istc_id, :as => :select, :collection => Istc.all
  = f.input :descriptivedetail_titledetail_titleelement_titlewithoutprefix
  %h3 Contributors
  #tasks
    = f.semantic_fields_for :linkers do |linker|
      = render 'linker_fields', :f => linker
    .links
      = link_to_add_association 'add contributor', f, :linkers
  -f.buttons do
    = f.submit 'Save'

isbns/_linker_fields.html.haml

isbns/_linker_fields.html.haml

.nested-fields
  = f.inputs do
    = f.input :contributor_id, :label_method => :keynames, :as => :select, :collection => Contributor.all
    = link_to_remove_association "remove contributor", f

Isbn.rb

  has_many :linkers
  has_many :contributors, :through => :linkers
  accepts_nested_attributes_for :contributors, :allow_destroy => true
  accepts_nested_attributes_for :linkers, :allow_destroy => true

contributor.rb

contributor.rb

  attr_accessible :linkers_attributes, :isbns_attributes
  has_many :isbns, :through => :linkers
  has_many :linkers
  accepts_nested_attributes_for :linkers

linker.rb

linker.rb

belongs_to :contributor
belongs_to :isbn
accepts_nested_attributes_for :contributor

结果

Started POST "/isbns/58" for 127.0.0.1 at 2011-06-09 12:34:14 +0100
  Processing by IsbnsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"u0TszLESOnZlr4iEiBlVg6w9B5T+EH0dxJg/0E6PKuQ=", "isbn"=>{"istc_id"=>"360", "descriptivedetail_titledetail_titleelement_titlewithoutprefix"=>"thurs title", "linkers_attributes"=>{"0"=>{"contributor_id"=>"3", "_destroy"=>"", "id"=>"68"}, "1"=>{"contributor_id"=>"71", "_destroy"=>"", "id"=>"69"}, "2"=>{"contributor_id"=>"72", "_destroy"=>"", "id"=>"70"}, "3"=>{"contributor_id"=>"3", "_destroy"=>"", "id"=>"71"}}}, "commit"=>"Save", "id"=>"58"}
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 2 LIMIT 1
  Isbn Load (8.2ms)  SELECT "isbns".* FROM "isbns" WHERE "isbns"."id" = 58 ORDER BY descriptivedetail_titledetail_titleelement_titlewithoutprefix LIMIT 1
  Linker Load (0.3ms)  SELECT "linkers".* FROM "linkers" WHERE "linkers"."id" IN (68, 69, 70, 71) AND ("linkers".isbn_id = 58)
  AREL (0.4ms)  UPDATE "linkers" SET "contributor_id" = 3, "updated_at" = '2011-06-09 11:34:14.509943' WHERE "linkers"."id" = 71
  Contributor Load (158.3ms)  SELECT "contributors".* FROM "contributors"
Redirected to http://localhost:3000/isbns/58
Completed 302 Found in 545ms

换句话说,从isbn编辑表单开始,它使用formtastic动态生成了嵌套的fields_for,我可以使用下拉菜单选择与isbns有多对多关系的现有贡献者.

In other words, from an isbn edit form which has dynamically produced nested fields_for, using formtastic, I can use a drop down menu to select an existing contributor which has a many to many relationship with isbns.

Ph.

这篇关于nested_form,collection_select,accepts_nested_attributes_for和fields_for,并将记录添加到联接表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆