質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.25%

動的フォームの入力内容が子テーブルに保存されない

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 28

na22ky

score 0

前提・実現したいこと

railsでレシピアプリ を作っています。
入力フォームから
・材料の名前と数量
・手順の番号と方法
を入力できるようにjqueryで動的フォームを作りました。
その内容をrecipesテーブルに紐付けたmaterialsテーブルとstepsテーブルに格納したいです。

発生している問題・エラーメッセージ

動的フォームに入力した値がデータベースに格納されません。

該当のソースコード

Recipe.rb

class Recipe < ApplicationRecord
  acts_as_taggable_on :labels
  acts_as_taggable 

  mount_uploader :image, ImageUploader

  has_many :materials
  has_many :steps
  accepts_nested_attributes_for :materials, allow_destroy: true
  accepts_nested_attributes_for :steps, allow_destroy: true
end


meterial.rb

class Material < ApplicationRecord
  belongs_to :recipe, optional: true
end


step.rb

class Step < ApplicationRecord
  belongs_to :recipe, optional: true
end


recipes_controller.rb

def index
    if params[:tag]
      @recipes = Recipe.tagged_with(params[:tag])
    else
      @recipes = Recipe.all
    end
  end

  def new
    @recipe = Recipe.new
    @recipe.materials.build
    @recipe.steps.build
  end

  def create
    binding.pry
    @recipe = Recipe.new(recipe_params)
    @recipe.save
    redirect_to root_path
  end

  private

  def recipe_params
    params.require(:recipe).permit(:title, :image, :calorie, :sugar, :tag_list, materials_attributes: [:name, :amount], steps_attributes: [:number, :process])
  end

end


new.html.erb

<div class="materials_field">
      <%= form.fields_for :materials, @recipe.materials do |material| %>
        <div class="material_field" id="material_field[0]">
        <%= material.text_field :name , placeholder: "食材", name: "name[0]", id:"name[0]" %>
        <%= material.text_field :amount, placeholder: "量", name: "amount[0]", id:"amount[0]" %> 
        </div>
        <%= form.button '▽追加する', id: "add_btn",type: "button"%>        
      <% end %>
    </div>
    <div class="steps_field">
      <%= form.fields_for :steps, @recipe.steps do |step| %>
        <div class="step_field" id="step_field[0]"> 
        <%= step.number_field :number , placeholder: "番号", name: "number[0]", id: "number[0]" %>
        <%= step.text_field :process, placeholder: "内容", name: "process[0]", id: "process[0]" %>
        </div> 
        <%= form.button '▽追加する', id: "add_btn2",type: "button" %>
      <% end %>
    </div>
    <div class="btn-send">
    <%= form.submit "投稿する" %>
    </div> 
  <% end %>
</div>    


recipes.js

$(function(){
  // フォームカウント
  var frm_cnt =0;
  // クローン
  $('#add_btn').on('click', function(){
    var original = $('#material_field\\[' + frm_cnt + '\\]');
    var originCnt = frm_cnt;

    frm_cnt++;

    original
      .clone()
      .appendTo(original)
      .attr('id', 'material_field[' + frm_cnt + ']')
      .end()
      .find('input, text_field').each(function(idx, obj) {
        $(obj).attr({
          id: $(obj).attr('id').replace(/\[[0-9]\]+$/, '[' + frm_cnt + ']'),
          name: $(obj).attr('name').replace(/\[[0-9]\]+$/, '[' + frm_cnt + ']')
        });         
        $(obj).val('');
      });
    });
  });

$(function(){
  // フォームカウント
  var frm_cnt =0;
  // クローン
  $('#add_btn2').on('click', function(){
    var original = $('#step_field\\[' + frm_cnt + '\\]');
    var originCnt = frm_cnt;

    frm_cnt++;

    original
      .clone()
      .appendTo(original)
      .attr('id', 'step_field[' + frm_cnt + ']')
      .end()
      .find('input, text_field').each(function(idx, obj) {
        $(obj).attr({
          id: $(obj).attr('id').replace(/\[[0-9]\]+$/, '[' + frm_cnt + ']'),
          name: $(obj).attr('name').replace(/\[[0-9]\]+$/, '[' + frm_cnt + ']')
        });
        $(obj).val('');
      });
    });  
});

試したこと

配列にしたデータがきちんと送られているのかbinding.pryを使い確認しました。
配列になり送られていることがわかりました。

<ActionController::Parameters {"utf8"=>"✓", "authenticity_token"=>"0MuSD4D8DxZnmhNQDERZ8hoNx8ElltdTUX179rMgm/vHuoonup8TmXE3XNyNYtU7126d5eVjWB0wJejEyo8q4Q==", "recipe"=><ActionController::Parameters {"title"=>"豆腐", "image"=>#<ActionDispatch::Http::UploadedFile:0x00007f9df4e72888 @tempfile=#<Tempfile:/var/folders/l5/89sfzxzj06q6rdkkxsynx8g00000gn/T/RackMultipart20200523-768-o3u0zy.jpg>, @original_filename="tohu.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"recipe[image]\"; filename=\"tohu.jpg\"\r\nContent-Type: image/jpeg\r\n">, "calorie"=>"100", "sugar"=>"4.0"} permitted: false>, "name"=>{"0"=>"豆腐", "1"=>"ねぎ"}, "amount"=>{"0"=>"1/2", "1"=>"少々"}, "number"=>{"0"=>"1", "1"=>"2"}, "process"=>{"0"=>"豆腐切る", "1"=>"ねぎ切る"}, "commit"=>"投稿する", "controller"=>"recipes", "action"=>"create"} permitted: false>


recipe_params[:name]を実行するとnilが返ってきました。

 pry(#<RecipesController>)> recipe_params[:name]
=> nil


ストロングパラメーターの記述が間違えていると考えましたが、どう試してもうまくいきません。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

ストロングパラメーターではなくjQueryの問題でした!
name属性を使わないと、動的フォームの最後の値のみデータベースに保存されます。
検証で見てみると、cloneしたフォームとされたフォーム全てのnameが同じだった為であることが分かりました。
name属性を使わないときに番号を振れるよう考えています!

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.25%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる