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 つのことは、作成後にコールバックを使用してデータベースを読み取ることでしたが、考慮しなければならない変数がたくさんあるため、安全ではありません。

更新 1: ほぼ完了しましたが、行き詰まりました

MurifoX ポインタのおかげで、 に割り当てられmenu_idた.hidden_fieldmenu_iddish

ただし、料理フォーム内に新しい料理と新しいカテゴリを作成しようとすると、新しいカテゴリ オブジェクトにカテゴリ ID が提供されていることを検証する、設定した検証エラーがスローされます。基本的に、は新しい Category オブジェクトのmenu_idに渡されません。hidden_field

一方、次のことができます。

  1. 料理を編集し、ネストされたフォームから新しいカテゴリを作成します。
  2. 独自の _form.html.haml ページから新しいカテゴリを作成します。
  3. 既存のカテゴリ項目を編集します。

しかし、私は単にできません:

  • ネストされたフォームから新しい料理と新しいカテゴリ項目を同時に作成します。

更新されたコードは次のとおりです。

_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