nested_form,collection_select,accepts_nested_attributes_for和fields_for,并将记录添加到连接表

更新:根据在这个问题的最后发布的堆栈跟踪,我认为真正的问题是要弄清楚我需要什么attr_accessible和构建关联设置才能使用新的isbn id更新贡献者和链接器属性。 请帮我!

继这个问题……

我有两个模型之间的连接表 – isbns和贡献者 – 它们有很多关系。 我想在使用fields_for的嵌套表单中的collection_select下拉列表中使用贡献者模型中的现有值。

因此,当我创建一个新的isbn时,我不想创建新的贡献者记录 – 我希望能够选择现有的记录。 我希望能够选择许多贡献者,这就是我使用nested_form gem的原因 ,它允许我为贡献者动态创建其他表单字段。

我的问题:我应该在连接表上调用方法吗? 如果是这样的话,为什么我会得到一个“丢失块”错误,尽管几乎所有东西都是attr_accessible和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:

 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:

 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:

   false do |f| %> 

Create new ISBN

f.object %> f %>

_fields :(选项1)

  
  • 当我真正希望新的链接器记录包含现有的contributor_id时,这将创建一个新的ISBN,以及具有正确的isbn_id的链接器中的新记录,但也是贡献者中的新记录。 所以我想我会这样做:

    _fields(选项2)

      
  • 但是这会返回一个丢失的块错误。

    非常感谢,我已经花了两天时间在这上面,并认为我可能会流行。

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

      
  • 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。 向前…

    好。 这是我如何做到的。

    安装了茧gem。 最后还安装了Haml,

    我拆分了新的和更新操作,所以新表单只是一个快速获取id设置,只有最少的字段。 然后用户可以编辑它,并添加贡献者。 从用户的角度来看并不是很糟糕,因为他们可以快速创建一个isbn,而不必填写无数的字段。

    ISBN号/ 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" 

    ISBN号/ _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' 

    ISBN号/ _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

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

    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 

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

    唷。