3
4

More than 3 years have passed since last update.

[rails]ストロングパラメータ受け取り時の400 bad requestの例と理由考察

Last updated at Posted at 2020-04-14

どんな事例

パラメータは投げ込めているのに受け取ることができないといったエラーでした。下記に詳細を示します。

エラー文(ターミナル上)の様子

Completed 400 Bad Request in 70ms (ActiveRecord: 32.8ms)



ActionController::ParameterMissing (param is missing or the value is empty: delete_images_ids):

app/controllers/items_controller.rb:163:in `delete_image_params'
app/controllers/items_controller.rb:62:in `update'

原因の記述とパラメータが投げ込まれている様子

app/assets/javascript/item_edit.js

$('#edit_item').on('submit', function(e){

  // 通常のsubmitイベントを止める
  e.preventDefault();
  // images以外のform情報をformDataに追加
  var formData = new FormData($(this).get(0));
  var url = $(this).attr('action')
  // 削除画像がない場合は便宜的に0を入れる
  if (clickdelete_registered_images_ids == gon.imageids) {
    formData.append("delete_images_ids[ids][]", 0)
    console.log(formData);
  // 削除画像で、のidをformDataに追加していく
  } else {
    clickdelete_registered_images_ids.forEach(function(delete_image_id){
      formData.append("delete_images_ids[ids][]", delete_image_id)
      console.log(formData);
    });
  }


  // 新しく追加したimagesがない場合は便宜的に空の文字列を入れる
  if (new_image_files.length == 0) {
    formData.append("new_images[images][]", " ")
  // 新しく追加したimagesがある場合はformDataに追加する
  } else {
    new_image_files.forEach(function(file){
      formData.append("new_images[images][]", file)
    });
  }

  $.ajax({
    url: url,
    type:        "PATCH",
    data:        formData,
    contentType: false,
    processData: false,
  })
});

パラメータを受け取れていない様子

app/controllers/items_controller
def delete_image_params
  #binding.pryをした結果は下記に示します
  params.require(:delete_images_ids).permit(ids:[])
end
From: /Users/kontatomoya/projects/freemarket_sample_62d/app/controllers/items_controller.rb:162 ItemsController#delete_image_params:

    161: def delete_image_params
 => 162:   binding.pry
    163:   params.require(:delete_images_ids).permit({ids:[]})
    164: end

[1] pry(#<ItemsController>)> params
=> <ActionController::Parameters {"utf8"=>"✓", "_method"=>"patch", "authenticity_token"=>"8Ld4lh2Zdf9r6wXZ9judJrqSMedhtgIdq2BqSJUtLurJqoHxVEWYWUiCjceulnnyXyl+4h99mEsAh213iYXtfQ==", "item"=>{"name"=>"お供", "text"=>"kkkkk", "category_id"=>"799", "condition_id"=>"4", "deliverycost_id"=>"1", "pref_id"=>"2", "delivery_days_id"=>"2", "price"=>"20000"}, "delete_images_ids"=>{"ids"=>["20", "22"]}, "new_images"=>{"images"=>[" "]}, "controller"=>"items", "action"=>"update", "id"=>"2"} permitted: false>

上記のように欲しい値は"delete_images_ids"=>{"ids"=>["20", "22"]}という形で投げ込まれていましたが受け取ることができませんでした

解決方法

最終的な決着としてどうなったかと言いますと、問題の根本は結局何かわからず、次の方法で迂回して解決を行いました。
①受け取り方をrequire(:item)に含めること
②ajax通信をやめるて通常のhtml通信のsubmitで送信すること(javascriptからではなくhtmlからデータを拾う形とすること)

理由考察

最終的には原因究明までは至りませんでしたが、原因の可能性は4つ感じており、今後の自分と、同じエラーで困っている方のお力になれればと思い記述させていただきます。結局は解決できていないため、可能性として目を通していただければと思います。

1.投げ入れた値が許可済みのものではなかった

ajax通信でjavascriptのformDataに配列名とその中身をappend(追記)して投げ込みませんでしたがRailsガイドの該当箇所(4.5.1 許可済みスカラー値)の中にformDataはないので弾かれてしまった。
(参考)Railsガイドの該当箇所(4.5 Strong Parametersの箇所をご覧ください)
https://railsguides.jp/action_controller_overview.html

2.一つのform_withに対して、送るモデルの数が2つ以上になってしまった

params.require(:item).permit(そのほかのもの,ids:[])にまとめたら動いたため

3.ajax通信で送る時に余計なデータが入った時に400エラーが起きるらしい

これに関しては手がかりはないのですが、検索すると出てくるらしいです

4..require()の中に入るシンボルがモデルに定義されていないと動かない

これは1番のRailsガイドを見ると.require()で投げ込むことができるモデルは〜という記述があるのでこれも一つ可能性があります。今の例も一応該当はしています

最後に

とりとめない記事になってしまったのですが、何かのきっかけにしていただければ幸いです。

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4