0

使用嵌套模型表单(修订版) Railscast 尝试使用可以立即更新的嵌套模型创建页面。Wiki 有很多主题,其中有很多注释。

问题是,a) 预先存在的数据没有按照正确执行的方式预先填充字段,并且 b) 点击更新不会引发任何错误(事实上,它显示了成功横幅),但它也没有做任何事情。

这是我的代码:

wiki、topic、note.rb(结合阅读,实际上并非如此):

class Wiki < ActiveRecord::Base
  attr_accessible :topics_attributes
  has_many :topics
  accepts_nested_attributes_for :topics, :allow_destroy => true
end
class Topic < ActiveRecord::Base
  attr_accessible :name, :notes_attributes, :wiki_id
  has_many :notes
  belongs_to :wiki
  accepts_nested_attributes_for :notes, :allow_destroy => true
end
class Note < ActiveRecord::Base
  attr_accessible :name, :info, :topic_id
  belongs_to :topic
end

wikis_controller.rb

我正在做 wiki.first 的事情,因为我只想要一个 wiki。该模型存在,因此我可以通过单个对象更新其依赖模型。我永远不会有超过一个维基。

class WikisController < ApplicationController
  before_filter :authorize

  def show
    @wiki = Wiki.first
  end

  def edit
    @wiki = Wiki.first
  end

  def update
    @wiki = Wiki.first
    respond_to do |format|
      if @wiki.update_attributes(params[:wiki])
        format.html { redirect_to wikis_path, notice: 'Wiki was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @wiki.errors, status: :unprocessable_entity }
      end
    end
  end

end

routes.rb # 我只想要一个“wiki”,我希望它的路线是 /wikis get 'wikis', to: 'wikis#show', as: 'home' resources: wikis

wikis/ edit.html.haml

.row.container.wiki
    %h1{ :style => 'margin-bottom: 40px'} Update the Wiki
    = form_for @wiki do |w|
        = w.fields_for :topics do |builder|
            = render "topic_fields", f: builder
        = link_to_add_fields "add topic", w, :topics
        %br
        = w.submit "Update", class: "btn"

wikis/ _topic_fields.html.haml

.field_inset
    = f.text_field :name
    = f.hidden_field :_destroy
    = link_to "remove", '#', class: "remove_fields"

    = f.fields_for :notes do |builder|
        = render 'note_fields', f: builder

维基/ _notes_fields.html.haml

.field_inset
    .add_inset
      = f.fields_for :notes do |builder|
        .remove
          = builder.text_field :name
          = builder.text_field :info, class: "no_margin"
          = link_to "remove", '#', class: "remove_fields"

这些类主要用于样式设置,但 remove_fields 除外,它调用了一些 javascript。知道我在这里做错了什么吗?我对此感到很困惑。

新错误

在修复了 wikis_controller 中的更新操作(错误地引用了 params[:post])之后,我现在在尝试提交更新时收到此错误。尽管如此,这些字段并未预先填充:

Can't mass-assign protected attributes: notes

我会认为 :topics_attributes 和 :notes_attributes 会处理这个问题?

另外,值得注意的是,虽然 Notes 字段没有预填充,但 Topics 字段是。

编辑——来自下面的质量分配错误的参数散列

看起来参数正在正确传递

{"utf8"=>"✓",
 "_method"=>"put",
 "authenticity_token"=>"3/4k8eEa4/PfeNI9cSj7zqCm9+scWBS3gwEacmc/hd0=",
 "wiki"=>{"topics_attributes"=>{"0"=>{"name"=>"Pre-existing Topic Name",
 "_destroy"=>"false",
 "notes_attributes"=>{"0"=>{"notes"=>{"name"=>"New Notes Name",
 "info"=>"New Notes Info"},
 "id"=>"1"}},
 "id"=>"1"}}},
 "commit"=>"Update",
 "id"=>"1"}
4

1 回答 1

1

您的视图中有一对多的fields_for调用。基本的经验法则是为每个accept_nested_attributes_for调用设置一个fields_for调用。

从以下位置更改 wikis/_notes_fields.html.haml:

.field_inset
    .add_inset
      = f.fields_for :notes do |builder|
        .remove
          = builder.text_field :name
          = builder.text_field :info, class: "no_margin"
          = link_to "remove", '#', class: "remove_fields"

至:

.field_inset
    .add_inset
      .remove
        = f.text_field :name
        = f.text_field :info, class: "no_margin"
        = link_to "remove", '#', class: "remove_fields"

我不是一个 haml 人,所以我不能 100% 确定这段代码是否有效,但基本想法是删除 fields_for 调用。

您的notes_attributes哈希如下所示:

"notes_attributes"=>{"0"=>{"notes"=>{"name"=>"New Notes Name",
                                     "info"=>"New Notes Info"}, "id"=>"1"}}

它应该:

"notes_attributes"=>{"notes"=>{"name"=>"New Notes Name",
                               "info"=>"New Notes Info"}}
于 2013-03-20T03:17:32.737 回答