【问题标题】:Need help understanding how to add and/remove objects within nested form需要帮助了解如何在嵌套表单中添加和/删除对象
【发布时间】:2013-01-15 23:38:04
【问题描述】:

我无法将数据从嵌套模型添加到我的数据库。

我的照片模型与怪物模型具有以下关系。我可以为怪物添加和删除我的嵌套表单,但在更新我的照片时无法弄清楚如何实际添加新的怪物对象。这是基于http://railscasts.com/episodes/196-nested-model-form-revised 示例中的 1 个嵌套级别表单,基本上展示了调查 - 问题关系。

class Photo < ActiveRecord::Base
  attr_accessible :title, :monsters_attributes

  has_and_belongs_to_many :monsters

  accepts_nested_attributes_for :monsters, allow_destroy: true
end

class Monster < ActiveRecord::Base
  attr_accessible :first_name, :last_name, :selected

  has_and_belongs_to_many :photos
end

我确定问题出在我的照片控制器上,并且我对如何使用更新照片表单时提交的参数了解不足。提交带有两个怪物的编辑照片表单时,我得到以下参数哈希。第一个已经关联,第二个我尝试通过单击“添加怪物”链接、输入名字和姓氏并提交表单来声明。

“添加怪物”链接是在我的 _form.html.erb 文件中为照片定义的,我正在使用部分渲染字段。辅助函数在 application_helper.rb 中声明。

_form.html.erb

…
    <!-- this uses the _monster_fields partial -->
    <%= f.fields_for :monsters do |builder| %>
      <%= render 'monster_fields', f: builder %>
    <% end %>        

  </table>

  <%= link_to_add_fields "Add Monster", f, :monsters %>
...

application_helper.rb

module ApplicationHelper

  def link_to_add_fields(name, f, association)
    new_object = f.object.send(association).klass.new  # make instance of monster association record, Monster.new
    id = new_object.object_id                          # get id of new monster object, id = Monster.new.object_id

    fields = f.fields_for(association, new_object, child_index: id) do |builder|
      render(association.to_s.singularize + "_fields", f: builder)    # render partial _monster_fields.html.erb
    end

    link_to(name, "#", class: "add_fields", data: {id: id, fields: fields.gsub("\n", '&#xA')}) # returns a link    
  end
end

编辑(更新)照片显示的参数:

{
"utf8"=>"✓", 
"_method"=>"put", 
"authenticity_token"=>"8dYkFrzdkulBv8YrZCHU2wfFh4v5LQc9q/JWPmsbDkc=", 
"photo"=>{"title"=>"Family Gathering", 
    "monsters_attributes"=>{
    "0"=>{"first_name"=>"Franken", "last_name"=>"Stein", "_destroy"=>"false", "id"=>"1"}, 
    "1358291763102"=>{"first_name"=>"Ware", "last_name"=>"Wolf", "_destroy"=>"false"}
    }, 
    "monster_ids"=>"1"
   }, 
"commit"=>"Update Photo", 
"action"=>"update", 
"controller"=>"photos", 
"id"=>"1"
}

在我的 applcation.js 文件中,我定义了如何处理字段的添加和删除。在 .add_fields 中,该示例使用我新创建的对象的 id,但我看不到如何将新创建的怪物保存在 monsters 表中。

application.js

$(document).ready(function() {

  $('form').on('click', '.remove_fields', function(event) {
    $(this).prev('input[type=hidden]').val('1');
    $(this).closest('tr').hide();
    event.preventDefault();
  });

  $('form').on('click', '.add_fields', function(event) {
    time = new Date().getTime();
    regexp = new RegExp($(this).data('id'), 'g');
    $(this).before($(this).data('fields').replace(regexp, time))    
    event.preventDefault();
  });

});

总的来说,这是一个非常简单的过程,但我不确定如何从我的照片编辑视图中实际保存一个新怪物(创建一个新的活动记录对象)。

我在使用多对多关系时会遇到问题吗?

来自 railscasts 的示例很好,但还没有走那么远。我很感激有人可能提供的任何帮助。

http://railscasts.com/episodes/196-nested-model-form-revised

13 年 1 月 16 日更新:我的参数哈希和我得到的错误

ActiveModel::MassAssignmentSecurity::PhotosController#update 中的错误

无法批量分配受保护的属性:monster_ids

app/controllers/photos_controller.rb:76:in block in update' app/controllers/photos_controller.rb:75:inupdate'

{"utf8"=>"✓",
 "_method"=>"put",
 "authenticity_token"=>"1l62Sged52hnEHQoj0WPf/asRjcIpIKBBzsb7gVDRm0=",
 "photo"=>{"title"=>"Family Gathering",
 "monsters_attributes"=>{"0"=>{"first_name"=>"Franken",
 "last_name"=>"Stein",
 "_destroy"=>"false",
 "id"=>"1"},
 "1358356969634"=>{"first_name"=>"Scary",
 "last_name"=>"Frank",
 "_destroy"=>"false"}},
 "monster_ids"=>"1"},
 "commit"=>"Update Photo",
 "id"=>"1"}

【问题讨论】:

    标签: ruby-on-rails nested-forms rails-activerecord


    【解决方案1】:

    嵌套属性的美妙之处在于不存在对控制器代码的影响。你可以继续做

    photo.update_attributes params[:photo]
    

    并且怪物将被适当地更新和删除:photo.monsters_attributes= 将由 update_attributes 使用来自params[:photo][:monsters_attributes] 的数据调用。调用accepts_nested_attributes_for 将(除其他外)创建一个合适的monsters_attributes= 方法

    【讨论】:

    • 谢谢。我想我几乎让它工作了。我目前在尝试用新怪物更新我的照片时遇到错误。错误:ActiveModel::MassAssignmentSecurity::PhotosController#update 中的错误无法批量分配受保护的属性:monster_ids app/controllers/photos_controller.rb:76:in block in update' app/controllers/photos_controller.rb:75:in update'
    • 你确实需要让 monsters_attributes 可以访问。我不确定 monsters_ids 参数来自哪里 - 它不应该是必需的
    • 我的照片模型中有 attr_accessible :title, :monsters_attributes。它需要在其他任何地方吗?也许 monsters_ids 是使用 has_and_belongs_to_many :monsters 形成的?
    • 我不记得在这种情况下看到了 association_name_ids。名为 photo[monster_ids] 的(可能是隐藏的)表单输入在哪里?
    • 好的,我发现了这个错误。我有一个流浪的下拉框,列出了我所有的怪物,所以当我提交表单时,它包含在参数中。哎呀!我可以在照片中添加新的怪物,它们出现在怪物表中,但是当我在编辑照片时使用删除链接时,添加的怪物仍然存在于我的怪物表中。不应该在表格中添加或删除处理吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-19
    • 2016-05-03
    相关资源
    最近更新 更多