Ruby on Railsで開発中、他の所と同じようにajax通信をする検索ダイアログをform_Tagで作ったところ以下の様なエラーがでて困ったと言う話です。
結論から言うと、
- form_tagやform_forの場合、 remoteオプションを使うと、authenticity_tokenのinputが自動で追加されない
- submit_tagとかbutton_tagとかのjavascript処理でauthenticity_tokenをmetaタグがから取ってくるようになっている
- すなわち、自力でjavascriptでsubmitするとauthenticity_tokenが追加される処理が走らない
っぽいです。
以下、rubyonrails.orgより抜粋。
Remote forms may omit the embedded authenticity token by setting config.action_view.embed_authenticity_token_in_remote_forms = false. This is helpful when you're fragment-caching the form. Remote forms get the authenticity token from the meta tag, so embedding is unnecessary unless you support browsers without JavaScript.
ajaxで処理をする様なフォームはfragment-cachingされているという前提のようですね。
確かにその場合、フォームの中にCSRFのタグを持っていると認証が通らなくなるので、html作成時に割り当てられたtokenをheaderのmetatagから取得する必要があると。
エラーになるコード
.d-flex.flex-row
=form_tag({controller: 'office', action: 'modal_search'}, {remote:true, id:"office_search"}) do
.px-3
=text_field_tag 'keyword'
.px-3
=button_tag t('cmn_sentence.searchButton',model:Business.model_name.human), class:"btn btn-secondary", onclick:"on_office_search_click()"
#office_search_message.py-3
検索後下のリストから選択して下さい
#office_search_list.d-flex
:javascript
function on_office_search_click(){
$('#office_search_message').text("検索中...")
$('#office_search').submit();
}
修正されたコード
.d-flex.flex-row
=form_tag({controller: 'office', action: 'modal_search'}, {remote:true, id:"office_search"}) do
.px-3
=text_field_tag 'keyword'
.px-3
=button_tag t('cmn_sentence.searchButton',model:Business.model_name.human), class:"btn btn-secondary", onclick:"on_office_search_click()"
#office_search_message.py-3
検索後下のリストから選択して下さい
#office_search_list.d-flex
:javascript
function on_office_search_click(){
$('#office_search_message').text("検索中...")
}
...そうなんです。romoteオプションがつけられたformはsubmitしちゃだめ。というだけでした。