React × Rails SPAの作成にあたりformオブジェクトを用いた実装をする必要があった。その際のレスポンスの返し方についてまとめておきます。
HTMLを返すだけなら苦労しない。
普通formオブジェクトでは以下の流れでデータを扱う
- コントローラーでストロングパラメータを用いてformから送信された値を受け取る
- formオブジェクトに定義したattr_accesorでストロングパラメータで許可したキーを受け取る
- saveメソッドなり保存処理を自前で実装。ActiveRecordのメソッドでDBに値を保存
- コントローラーでredirectなどを用いてページをレンダリング
3で保存処理をした後はformオブジェクトの役目は終わる。
json形式のレスポンスをどう返すか?
ところがSPAでフロントエンドから非同期でAPIを動かす場合はjson形式でレスポンスを返さないといけない。
そこで以下のようにハッシュ形式で保存した複数のモデルをsaveメソッドの戻り値とする。
def save
hoge = Hoge.new(some_column: some_value)
fuga = Fuga.new(some_column: some_value)
# 別々にレスポンスとして扱うためにハッシュ形式を採用(配列でもいけるが、なんのデータなのかわかりやすくしたい)
hash = {}
hash[:hoge] = hoge
hash[:fuga] = fuga
return hash #生成したハッシュをコントローラーに返し、レスポンスにする
end
こうするとコントローラーでhashから値を取り出す形でjson形式のレスポンスを定義できる。
def create
@test = Test.new(test_params)
if @output.valid?
test_save_result = @test.save
# ステータスは手動で設定する。リソース保存時のステータスは201
render status: 201, json: { hoge: test_save_result[:hoge], fuga: test_save_result[:fuga] }
else
render status: 422, json: { errors: @test.errors.full_messages }
end
end