rails strong parametersの使い方とハマったところ
基本的なつかい方
送信する方はとりあえずjqueryでこんなイメージ
$.ajax({ type: "POST", url: "https://example.com/books", data: JSON.stringify({ title: 'タイトル', description: '説明' }), contentType: 'application/JSON' });
今回使うテーブルはbooksでtitleとdescriptionカラムをもつ。modelはこんな感じ
class Book < ApplicationRecord validates :title, presence: true validates :description, presence: true end
コントローラ
class BooksController < ApplicationController def create Book.create!(book_params) head :created rescue ActionController::UnpermittedParameters => e head :bad_request rescue StandardError => e head :internal_server_error end private def book_params params.require(:book).permit(:title, :description) end end
ハマったところ
wrap_parameters
postで送信すると、送信したデータがparamsにcontroller名のハッシュとしてセットされる。例えば、/path/to/booksというURLに{ title:'タイトル', description: '説明' }をjson形式でpostするとparams[:book]とうハッシュにセットされる。json形式でなく、postするとそのままparams[:title]、params[:description]がセットされる。これは、wrap_parametersという機能らしくrailsのデフォルトの設定のままだとこのようになる。
requireの中のpermitで指定してない項目があってもエラーにならない
例えば上記の例で{ title:'タイトル', description:'説明', hoge:'ほげ' }みたいなデータを送信するとUnpermittedParametersがraiseされると思っていた。が、実際にはraiseされない。ただし、json形式でない形で送信した場合にrequireせずに以下のようなコードを書くとhogeは許可されていないのでUnpermittedParametersがraiseされる。
def book_params params.permit(:title, :description) end
paramsにformatが自動で付与される
jsonで送信するとparams[:format]='json'という値が勝手にセットされて以下のようなエラーが出る。勝手につけたパラメータでエラーになるってよくわからないが、require(:book)みたいな使い方をされる前提なのかもしれない。
found unpermitted parameters: :format
パラメータ名がmodelと同じだとparamsの中身がフィルタリングされる
以下のプログラムにして{ title:'タイトル', description:'説明', hoge:'ほげ' }というデータを送信。permitに:hogeを追加したのにbook_paramsの中身には:hogeがなくなってる。
def create book_params ## book_params -> { title:'タイトル', description:'説明' } ・・・ end private def book_params params.require(:book).permit(:title, :description, :hoge) end
ちなみにbooksモデルを削除して実行したらbook_paramsに:hogeはちゃんといた。ちゃんとmodelと連携までしてるのか。裏で色々やってくれてるのでわからなくなる、、
わかりずらい文章だが、以上です