前回の振り返り
前回は Rails でシンプルな GET のみの API を実装した。
前回生成されたファイルたちは下記。
一部改善を入れる
1. migration
db/migrate/20230423145010_create_bank_transactions.rb
bank_transactions テーブルで
下記のカラムを生成するマイグレーション定義。
- 口座番号: 文字列
- 金額: 少数
- 説明: 文字列
- createdAt
- updatedAt
class CreateBankTransactions < ActiveRecord::Migration[7.0]
def change
create_table :bank_transactions do |t|
t.string :account_number
t.decimal :amount
t.string :description
t.timestamps
end
end
end
2. seed -- 一部改善
テストデータを入れるところ。
かえでは開発で一番大事だと考えている。
db/seeds.rb
下記のカラムに挿入される初期データ。
- 口座番号: 文字列
- 金額: 少数
- 説明: 文字列
BankTransaction.delete_all
BankTransaction.create!(
[
{
account_number: "1234567",
amount: 250_000,
description: "おちんぎん"
},
{
account_number: "1234567",
amount: -21_000,
description: "奨学金"
},
{
account_number: "1234567",
amount: -3_000,
description: "docomo携帯料金"
},
]
)
puts "BankTransaction records: "
BankTransaction.all.each do |bank_transactions|
json = bank_transactions.as_json
pretty_json = JSON.pretty_generate(json)
puts pretty_json
end
一番最初に全てのデータを削除する。
その後 3 レコード挿入している。
また、挿入後に結果を出力するカスタムスクリプトも入れている。
!
マークは、型が違った時に適切なエラーを返す。
この場合は RecordInvalid
が返ってくる。
!
マークなしだと false で返ってくるので、原因の特定に時間がかかるだろう。
3. Models
app/models/bank_transaction.rb
BankTransaction クラスに ApplicationRecord を継承させている。
class BankTransaction < ApplicationRecord
end
ApplicationRecord とは ActiveRecord を使うためのもの。
ActiveRecord とは Rails の ORM。
ORM とはデータベースのレコードを、Rails で扱える インスタンス
にするもの。
これによって、DB のテーブルを使って、
- 1対多のアソシエーション
- 必須やユニークのバリデーション
これらを作ることができる。
今回はまだ導入していない。
3.5 Route
まずこれを通さないと、コントローラーまで行かない。
config.route.rb を編集する。
resources :bank_transactions, only: [:index, :show]
生成時には
- GET ALL の index
- GET DETAIL の show
これらのみが有効化されている。
- CREATE
- UPDATE
- DELETE
これらは無効化されている。
resources :bank_transactions, only: [:index, :show, :create, :udate, :delete]
こうすることで有効化できる。
4. Controllers
4.0 共通メソッド
rails コマンドで生成されている。
class BankTransactionsController < ApplicationController
before_action :set_bank_transaction, only: %i[ show update destroy ]
-
before_action: methodName
を使うと、各 CRUD アクションが実行されたる直前に methodName が発火する -
only:
によって create 以外に絞られる。
set_bank_transaction は以下になっている
private
# Use callbacks to share common setup or constraints between actions.
def set_bank_transaction
begin
@bank_transaction = BankTransaction.find(params[:id])
rescue ActiveRecord::RecordNotFound
render json: {
status: 404,
error: "bank_transaction Not Found"
},
status: :not_found
end
end
引数の id で BankTransaction のエンティティを引っ張る。
それを @bank_transaction というインスタンス変数に詰める。
インスタンス変数は、同一名の Controlle の他のアクションや、View で使うことができる変数。
今回は View はないが、show, update, delete のアクションがある。
これらで @bank_transaction を使用できる。
id のデータが存在しないときのエラーハンドリングも入れておく。
(カスタマイズ)
これを入れないと exception メッセージが長くてデバックが面倒。
自動で下記のアクションが作成されている。
4.1 GET ALL
# GET /bank_transactions
def index
@bank_transactions = BankTransaction.all
render json: @bank_transactions
end
[
{
"id": 14,
"account_number": "1234567",
"amount": "250000.0",
"description": "おちんぎん",
"created_at": "2023-05-04T15:29:45.998Z",
"updated_at": "2023-05-04T15:29:45.998Z"
},
{
"id": 15,
"account_number": "1234567",
"amount": "-21000.0",
"description": "奨学金",
"created_at": "2023-05-04T15:29:46.002Z",
"updated_at": "2023-05-04T15:29:46.002Z"
},
{
"id": 16,
"account_number": "1234567",
"amount": "-3000.0",
"description": "docomo携帯料金",
"created_at": "2023-05-04T15:29:46.006Z",
"updated_at": "2023-05-04T15:29:46.006Z"
}
]
4.2 GET Detail
# GET /bank_transactions/1
def show
render json: @bank_transaction
end
{
"id": 15,
"account_number": "1234567",
"amount": "-21000.0",
"description": "奨学金",
"created_at": "2023-05-04T15:29:46.002Z",
"updated_at": "2023-05-04T15:29:46.002Z"
}
4.3 POST (create)
-d {key:value} でデータをつける
-X POST で POST メソッドにする
-i でレスポンスコードを見る
これで POST する。
curl -i -X POST -H "Content-Type: application/json" \
-d '{"account_number": "1234567", "amount": 997777.0, "description": "POST TEST "}' \
http://localhost:3000/bank_transactions
HTTP/1.1 201 Created
...
{"id":22,"account_number":"1234567","amount":"997777.0","description":"POST TEST ","created_at":"2023-05-07T05:22:20.825Z","updated_at":"2023-05-07T05:22:20.825Z"}%
すると、新しくデータができている
4.4 PUT
# PATCH/PUT /bank_transactions/1
def update
if @bank_transaction.update(bank_transaction_params)
render json: @bank_transaction
else
render json: @bank_transaction.errors, status: :unprocessable_entity
end
end
curl localhost:3000/bank_transactions/23 | jq .
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 168 0 168 0 0 8351 0 --:--:-- --:--:-- --:--:-- 12923
{
"id": 23,
"account_number": "1234567",
"amount": "250000.0",
"description": "おちんぎん",
"created_at": "2023-05-07T07:35:04.777Z",
"updated_at": "2023-05-07T07:35:04.777Z"
}
curl -i -X PUT \
-H "Content-Type: application/json" \
-d '{"account_number": "1234567", "amount": 300000, "description": "昇給!"}' \
http://localhost:3000/bank_transactions/23
HTTP/1.1 200 OK
curl localhost:3000/bank_transactions/23 | jq .
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 162 0 162 0 0 8197 0 --:--:-- --:--:-- --:--:-- 12461
{
"id": 23,
"account_number": "1234567",
"amount": "300000.0",
"description": "昇給!",
"created_at": "2023-05-07T07:35:04.777Z",
"updated_at": "2023-05-07T07:40:21.788Z"
}
4.5 DELETE (destroy)
リソースを「破壊」する。
# DELETE /bank_transactions/1
def destroy
@bank_transaction.destroy
end
curl localhost:3000/bank_transactions/24 | jq .
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 162 0 162 0 0 8152 0 --:--:-- --:--:-- --:--:-- 12461
{
"id": 24,
"account_number": "1234567",
"amount": "-21000.0",
"description": "奨学金",
"created_at": "2023-05-07T07:35:04.782Z",
"updated_at": "2023-05-07T07:35:04.782Z"
}
curl -i -X DELETE \
-H "Content-Type: application/json" \
http://localhost:3000/bank_transactions/23
HTTP/1.1 204 No Content
curl localhost:3000/bank_transactions/23 | jq .
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 15874 100 15874 0 0 375k 0 --:--:-- --:--:-- --:--:-- 455k
{
"status": 404,
"error": "Not Found",
"exception": "#<ActiveRecord::RecordNotFound: Couldn't find BankTransaction with 'id'=23>",
Top comments (0)