【初学者向け】Ruby on Railsを用いてTODOリストを管理するAPIを作ってみた
IT技術
はじめに
現在の業務では、バックエンドでRuby on Railsを使用しています。私はSwift・ReactNativeなどのモバイルの技術を触ってきたので、サーバーサイドの知見が少ないです。今回はサーバーサイドの概要を理解するために、TODOリストを管理するAPIを作成していきます。この記事はAPIを作成し、ローカル環境で起動し、HTTPリクエストにおけるGET・POST・PUT・DELETEメソッドなどの基本的な部分を理解することを目的に記載しています。公式ドキュメントを参考にしながら理解を進めていきます。
プロジェクトの作成
1rails new todo_api --api
--api を指定することで、APIモードでのアプリケーション作成を指示しています。これにより、Railsアプリケーションがフルスタックのウェブアプリケーションではなく、単純なAPIエンドポイントとして構築されます。データベースは、デフォルトでsqliteが適応されます。
プロジェクトディレクトリに移動
1cd todo_api/
モデルの作成
1rails g model TodoItem title:string description:text completed:boolean
出力結果
1invoke active_record
2create db/migrate/20240314091844_create_todo_items.rb
3create app/models/todo_item.rb
4invoke test_unit
5create test/models/todo_item_test.rb
6create test/fixtures/todo_items.yml
TodoItemモデルとそれに対応するマイグレーションファイルが生成されます。
生成された
- app/models/todo_item.rb
- db/migrate/20240314091844_create_todo_items.rb
ファイルの中身の実装を見てみましょう。
app/models/todo_item.rb
1class TodoItem < ApplicationRecord
2end
TodoItemという名前でモデルが定義されています。ApplicationRecordは、Railsのすべてのモデルが継承するデフォルトのベースクラスです。このクラスを継承することで、データベースとの連携が可能になります。
db/migrate/20240314091844_create_todo_items.rb
1class CreateTodoItems < ActiveRecord::Migration[7.1]
2 def change
3 create_table :todo_items do |t|
4 t.string :title
5 t.text :description
6 t.boolean :completed
7
8 t.timestamps
9 end
10 end
11end
このマイグレーションファイルは、CreateTodoItemsという名前でマイグレーションを定義しています。todo_itemsという名前の新しいテーブルをデータベースに作成します。
マイグレーションの実行
1rails db:migrate
出力結果
1== 20240314091844 CreateTodoItems: migrating ==================================
2-- create_table(:todo_items)
3-> 0.0008s
4== 20240314091844 CreateTodoItems: migrated (0.0008s) =========================
コントローラの作成
TODOItemsのコントローラを作成します。
1rails g controller TodoItems
出力結果
1create app/controllers/todo_items_controller.rb
2invoke test_unit
3create test/controllers/todo_items_controller_test.rb
app/controllers/todo_items_controller.rbファイルが生成されます。
実装
routesファイルの修正
1
2Rails.application.routes.draw do
3 resources :todo_items
4end
リソースベースのルーティングを使うことで、リソースベースで構成されたコントローラに対応する共通のルーティングを手軽に宣言できます。resourcesを宣言するだけで、コントローラのindex、show、new、edit、create、update、destroyアクションを1行で宣言が完了します。
TodoItemsControllerの実装
1class TodoItemsController < ApplicationController
2 #このクラス内に、実装していく。
3end
TodoItemsControllerクラス内にindex、show、new、edit、create、update、destroyアクションを実装していきます。
特定のアクション時の事前に行う処理
1before_action :set_todo_item, only: [:show, :update, :destroy]
- 特定のアクションが実行される前に、指定されたメソッド(set_todo_item)を実行することを示しています
- :set_todo_item メソッドは、後で実装していきます
- :only オプションは、このフィルターが適用されるアクションを指定します。この場合、:show、:update、:destroy アクションが実行される前に set_todo_item メソッドが実行されます。
共通する処理の共通化
1private
2 def set_todo_item
3 @todo_item = TodoItem.find(params[:id])
4 end
5
6 def todo_item_params
7 params.require(:todo_item).permit(:title, :description, :completed)
8 end
- set_todo_item メソッド:
このメソッドは、指定したToDoを検索してインスタンス変数 @todo_item に割り当てるためのものです。params[:id] を使用して、リクエストのURLからToDoのIDを取得し、それを使用してデータベースから該当するToDoを検索します。
- todo_item_params メソッド:
このメソッドは、Strong Parametersを使用してToDoのパラメーターを取り出します。params.require(:todo_item) を使用して、todo_item パラメーターを要求し、.permit(:title, :description, :completed) を使用して許可されたリストを指定します。
GETメソッドの処理
1def index
2 @todo_items = TodoItem.all
3 render json: @todo_items
4end
- index アクションは、HTTP GETリクエストにより実行されます
- TodoItem.all を使用してデータベースからすべてのToDoを取得し、インスタンス変数 @todo_items に格納します
- 取得したToDoの一覧をJSON形式でレスポンスとして返します
POSTメソッドの処理
1def create
2 @todo_item = TodoItem.new(todo_item_params)
3
4 if @todo_item.save
5 render json: @todo_item, status: :created
6 else
7 render json: @todo_item.errors, status: :unprocessable_entity
8 end
9 end
- create アクションは、HTTP POSTリクエスト送信された場合に実行されます
- @todo_item.save を使用してToDoをデータベースに保存しようとします。保存が成功した場合は、作成されたToDoをJSON形式でレスポンスとして返します
- 保存に失敗した場合は、エラーメッセージを含むJSON形式のレスポンスを返します
PUTメソッドの処理
1def update
2 if @todo_item.update(todo_item_params)
3 render json: @todo_item
4 else
5 render json: @todo_item.errors, status: :unprocessable_entity
6 end
7 end
- update アクションは、HTTP PUTリクエストが送信された場合に実行されます
- アクション内では、@todo_item.update(todo_item_params)を使用して、ToDoを更新しようとします
- 更新が成功した場合は、更新されたToDoをJSON形式でレスポンスとして返します
- 更新に失敗した場合は、エラーメッセージを含むJSON形式のレスポンスを返します
DELETEメソッドの処理
1
2 def destroy
3 @todo_item.destroy
4 head :no_content
5 end
- destroy アクションは、HTTP DELETEリクエストが送信された場合に実行されます
- アクション内では、@todo_item.destroy を使用して、指定されたToDoをデータベースから削除します
挙動の確認
サーバーの起動
1rails server
TODOリストの確認
1curl http://localhost:3000/todo_items
出力結果
1[]%
TODOリストの追加
1curl -X POST -H "Content-Type: application/json" -d '{"todo_item": {"title": "New Task", "description": "Description of the task", "completed": false}}' http://localhost:3000/todo_items
出力結果
1{
2"id":2,
3"title":"New Task",
4"description":"Description of the task",
5"completed":false,
6"created_at":"2024-03-15T02:34:01.234Z",
7"updated_at":"2024-03-15T02:34:01.234Z"
8}
TODOリストの更新
先ほど追加したTODOのcompletedの値を変更する。
1curl -X PATCH -H "Content-Type: application/json" -d '{"todo_item": {"completed": true}}' http://localhost:3000/todo_items/2
出力結果
1{
2"id":2,
3"title":"New Task",
4"description":"Description of the task",
5"completed":true, ←更新された
6"created_at":"2024-03-15T02:34:01.234Z",
7"updated_at":"2024-03-15T02:34:59.757Z" ←更新された
8}
変更されたあとの値が出力されるため、正しい挙動が確認できました。
TODOリストの削除
1curl -X DELETE http://localhost:3000/todo_items/2
TODOリストの確認
1curl http://localhost:3000/todo_items
出力結果
1[]%
TODOは削除されており、空のjsonが出力されました。
以上で、正しいCRUD処理の挙動を確認することができました。
まとめ
今回はバックエンドを少しでも理解したいと思い、TODOリストの管理を目的とするAPIを実装しました。基本的なCRUD処理を実施し、API構築の大まかな流れを理解することができました。実際の実務のコードを見ても理解できていない部分が多いものの、ディレクトリ・ファイルの役割を少し理解することができました。次回以降の記事で今回実装したAPIを用いて、Reactnativeで実装していきます。
ライトコードでは、エンジニアを積極採用中!
ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。
採用情報へ