0

我在我的 Rails 应用程序中使用嵌套表单 ( RailsCast #196 )。这是我目前的问题以及我想做的事情;但是,我不确定解决此问题的最佳方法是什么,并希望得到一些指示。

我有一个dish表单 ( _form.html.haml),其中包含以下一些字段:

.control-group
  =f.label :menu, :class => 'control-label'
  .controls
    =select("dish", "menu_id", (current_user.has_role? :admin) ? (Menu.all.collect {|m| [ m.name, m.id ] }) : (current_user.menus.all.collect {|m| [ m.name, m.id ] }), {:include_blank => 'Choose a Menu'})
.control-group
  =f.label :name, :class => 'control-label'
  .controls
    =f.text_field :name

.control-group
  =f.label :category_ids, "Category", :class => 'control-label'
  .controls
    =f.collection_select :category_ids, (current_user.has_role? :admin) ? (Category.order(:name)) : (current_user.categories.order(:name)), :id, :name, params[:category_id].nil? ? {} : {:selected => params[:category_id]}, {multiple: true, :class => 'chzn-select'}

  .controls
    %p.help-block
      =link_to_add_fields "Add New Category", f, :categories, "categories"

从文件中=link_to_add_fields生成嵌套表单_category_fields.html.haml,此函数在 my 中定义application_helper.rd为:

def link_to_add_fields(name, f, association, parent)
  new_object = f.object.send(association).klass.new
  id = new_object.object_id
  fields = f.fields_for(association, new_object, child_index: id) do |builder|
    render(parent + "/" + association.to_s.singularize + "_fields", f: builder)
  end
  link_to(name, '#', class: "add_fields", data: {id: id, fields: fields.gsub("\n", "")})
end

我的category部分形式 ( _category_fields.html.haml) 看起来像这样:

%fieldset
  .control-group
    %h5
      New Category
      
    =f.select("menu_id", (current_user.has_role? :admin) ? (Menu.all.collect {|m| [ m.name, m.id ] }) : (current_user.menus.all.collect {|m| [ m.name, m.id ] }), {:include_blank => 'Choose a Menu'})
    =f.hidden_field :_destroy
    
    =f.text_field :name, placeholder: "Name"
    
    =link_to "X", "#", :class => "remove_fields"

您会注意到,用户已经在下拉菜单menu_id中的表单中选择并定义了:dish

.control-group
  =f.label :menu, :class => 'control-label'
  .controls
    =select("dish", "menu_id", (current_user.has_role? :admin) ? (Menu.all.collect {|m| [ m.name, m.id ] }) : (current_user.menus.all.collect {|m| [ m.name, m.id ] }), {:include_blank => 'Choose a Menu'})

但您也注意到,我强迫用户从嵌套表单的部分表单中的menu_id另一个下拉列表中重新选择。category

我想要它,这样menu_id用户就不需要在嵌套表单中重新选择它,而是在用户点击提交按钮后通过从传递给的参数中检测它来category分配给新项目category数据库。

例如,当您点击提交按钮时,终端/控制台会显示以下内容:

Started POST "/dishes" for 127.0.0.1 at 2012-08-06 09:51:41 -0700
Processing by DishesController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"tAbx+14Ve22FVimgY0x2d+fbImuG+pjkgC7Zgdco73k=", "dish"=>{"menu_id"=>"1", "name"=>"New Dish", "category_ids"=>["", "2"], "categories_attributes"=>{"1344271336031"=>{"menu_id"=>"1", "_destroy"=>"false", "name"=>""}} ... }}

menu_id重申一下,我希望"categories_attributes"=>{"1344271336031"=>{"menu_id"=>"1"...通过拿起"dish"=>{"menu_id"=>"1" ....

我假设最好的方法是通过 jQuery,但是当谈到 jQuery 时,我是一个完整的新手,并且不知道如何开始以及在线研究要寻找什么。

我尝试的另一件事是在创建后使用回调并读取数据库,但这是不安全的,因为我需要考虑许多变量。

更新 1:几乎就在那里,但卡住了

多亏了 MurifoX 指针,我可以menu_id通过hidden_field在嵌套表单中menu_id分配dish.

但是,当我在菜式表单中创建一个新的 Dish 和一个新的 Category 时,它会抛出我设置的验证错误,该错误验证是否已为新的 Category 对象提供了一个类别 ID。所以基本上,menu_id没有被传递到hidden_field新的 Category 对象中。

另一方面,我能够:

  1. 编辑 Dish 并从嵌套表单创建一个新类别。
  2. 从其自己的 _form.html.haml 页面创建一个新类别。
  3. 并编辑现有的类别项目。

但我根本不能:

  • 同时从嵌套表单创建一个新的 Dish 和一个新的 Category 项。

这是我更新的代码:

_category_fields.html.haml

...
=f.hidden_field :menu_id, :value => @dish.nil? ? [:dish][:menu_id] : @dish.menu_id
...

类别控制器.rb

def create      
  if @dish.blank?
    @category = Category.new(params[:category])
  else
    @category = Category.new(:menu_id => [:dish][:menu_id], :name => [:category])
  end

  respond_to do |format|
    if @category.save
      format.html { redirect_to categories_path, notice: 'Category was successfully created.' }
    else
      format.html { render action: "new" }
    end
  end
end

def update
  @category = Category.find(params[:id])

  respond_to do |format|        
    if @dish.blank?
      if @category.update_attributes(params[:category])
        format.html { redirect_to categories_path, notice: 'Category was successfully updated.' }
      else
        format.html { render action: "edit" }
      end
    else
      if @category.update_attributes(:menu_id => [:dish][:menu_id], :name => [:category])
        format.html { redirect_to categories_path, notice: 'Category was successfully updated.' }
      else
        format.html { render action: "edit" }
      end
    end
  end
end
4

0 回答 0