Posted at

Rails-APIでTODOアプリを作る。

More than 3 years have passed since last update.


はじめに

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リソースの作成

titledescriptionを持つ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フレームワークで煮るなり焼くなり。

おしまい。