はじめに
Rails5にrails-apiが取り込まれることになったので、
rails-apiを使って簡単なTODOアプリを作ってみましょう。
環境
Ruby 2.2.3
Rails 4.2.6
1.プロジェクトの準備
ビューに関連する機能は必要ないので、rails-api
を使用します。
$ gem install rails-api
$ rails-api new todo-api
2.TODOリソースの作成
title
とdescription
を持つTodoモデルとコントローラを作成します。
$ bin/rails g scaffold todo title:string description:text
Running via Spring preloader in process 98946
invoke active_record
create db/migrate/20160405125716_create_todos.rb
create app/models/todo.rb
invoke test_unit
create test/models/todo_test.rb
create test/fixtures/todos.yml
invoke api_resource_route
route resources :todos, except: [:new, :edit]
invoke scaffold_controller
create app/controllers/todos_controller.rb
invoke test_unit
create test/controllers/todos_controller_test.rb
dbのマイグレーションをします。
$ bundle exec rake db:migrate
== 20160405125716 CreateTodos: migrating ======================================
-- create_table(:todos)
-> 0.0014s
== 20160405125716 CreateTodos: migrated (0.0015s) =============================
3.Strong Parametersの一部を修正
controllers/todos_controller.rb
〜省略〜
private
def set_todo
@todo = Todo.find(params[:id])
end
def todo_params
# params.require(:todo).permit(:title, :description)の .require(:todo)を削除
params.permit(:title, :description)
end
end
4.レスポンスの整形
ActiveModel::Serializer
を使用してレスポンスを整形します。
gem 'active_model_serializers'
デフォルトではレスポンスにルートノード(todo
の部分)が付与されるので無効にします。
{"todo":{"id":2,"title":"優先タスク","description":"とても重要なタスクです。"}}
config/initializers/active_model_serializers.rb
ActiveSupport.on_load(:active_model_serializers) do
ActiveModel::Serializer.root = false
ActiveModel::ArraySerializer.root = false
end
TODOモデル用のSerializerを作成します。
レスポンスに含めたい項目のみをattributes
に定義します。
app/serializers/todo_serializer.rb
class TodoSerializer < ActiveModel::Serializer
attributes :id, :title, :description
end
コントローラを修正します。
app/controllers/todos_controller.rb
class TodosController < ApplicationController
before_action :set_todo, only: [:show, :update, :destroy]
# GET /todos
# GET /todos.json
def index
@todos = Todo.all
render json: @todos.map { |todo| TodoSerializer.new(todo)}
end
# GET /todos/1
# GET /todos/1.json
def show
render json: TodoSerializer.new(@todo)
end
~省略~
修正後の結果。
$ curl http://localhost:3000/todos/2
{"id":2,"title":"優先タスク","description":"とても重要なタスクです。"}
5.CRUDの確認
TODOの作成
$ curl -H "Content-Type:application/json; charset=utf-8" -X POST -d '{ "title":"優先タスク", "description":"とても重要なタスクです。" }' http://localhost:3000/todos
TODOの更新
$ curl -H "Content-Type:application/json; charset=utf-8" -X PATCH -d '{ "title":"優先タスク", "description":"かなりやばいタスクです。" }' http://localhost:3000/todos/1
TODOの取得
$ curl http://localhost:3000/todos/1
{"id":1,"title":"優先タスク","description":"とても重要なタスクです。"}
TODO一覧の取得
$ curl http://localhost:3000/todos
[{"id":1,"title":"優先タスク","description":"とても重要なタスクです。"},{"id":2,"title":"普通のタスク","description":"普通のタスクです。"}]
TODOの削除
$ curl http://localhost:3000/todos/1 -X DELETE
あとはお好きなJSフレームワークで煮るなり焼くなり。
おしまい。