Rails5のAPIモードでform_forのエラーにハマった話

railsアイキャッチ画像

どうも、エンジニアブロガーのYutaです。最近Rails5のAPIモードでの開発が多いのですが、通常モードと同じ感覚でformヘルパーを使ったらしばらくエラーにハマってしまいました。

APIモードと通常モードの違いをしっかり理解していれば何も問題ないのですが、ようやく自分の中で理解できたので記事にしようとも思います。

動作環境

  • Rails => Rails 5.0.6
  • Ruby => ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-linux]
  • 開発環境 => cloud9

記述コード

config/routes.rb

Rails.application.routes.draw do
  get "hoge/new" => "hoges#new"
  post "hoge/create" => "hoges#create"
end

app/views/hoges/new.html.erb

<h1>予約登録</h1>
<%= form_for (@hoges) do |f| %>
    <p>
      <%= f.label(:hoge, "開始時間") %>
      <%= f.datetime_local_field :start_time %>
    </p>
    <p>
      <%= f.label(:hoge, "終了時間") %>
      <%= f.datetime_local_field :last_time %>
    </p>
    <p>
      <%= f.submit %>
    </p>
<% end %>

app/controllers/hoges_controller.rb

class HogesController < ApplicationController

    def new
      @hoges = Hoges.new
    end

    def create

      @hoges = Hoges.new(hoge_params)
        if @frames.save
          render :text => "登録完了"
        else
          render :text => "登録失敗"
        end
     end

     private 
       def hoge_params
         params.require(:hoge).permit(:start_time, :last_time)
       end
end

エラーの原因

rails new --apiコマンドでアプリケーションを新規作成した際、Railsは「ビューが全く無い純粋なAPIを作らなければ!」と解釈して、Viewに関連するgemなどはインストールしないようになります。

特に、通常のアプリ開発で必須であるCSRF対策はAPIモードだと不要と解釈されるみたい。

そのため、form_forで作成したフォームでsubmitを押すと、次のようなエラーが発生します。

ActionView::Template::Error undefined method protect_against_forgery? for #<#<Class:0x0000000384bdd8>:0x00000003849dd0>>",

このエラーを解消するためには、hoge_cotrollerapplication_controllerを介して継承しているActionController::APIActionController::Baseに変更すればOK。

これでsubmitを押してもundefined method protect_against_forgery?のエラーが発生することはなくなるはずです。

通常モードとAPIモードの詳しい差分について知りたい方は、以下のQiita記事がよくまとめられているのでおすすめです!

参考記事

Rails APIモードのdiff

最後に

エラーに何回も遭遇していると、だいたいここが怪しいのでは?と見当がつくようになりますよね。

以前の自分ならこのエラー解消に1週間とか掛かっていたかもしれません笑

これからも開発を続けてスキルアップして行きたいと思います!

それでは、また!