DEV Community

kaede
kaede

Posted on • Edited on

Rails 基礎 Part 02 -- 3 カラムの Migration ファイルから作成した API の振り返り + 改善

前回の振り返り

前回は Rails でシンプルな GET のみの API を実装した。
前回生成されたファイルたちは下記。
一部改善を入れる


1. migration

db/migrate/20230423145010_create_bank_transactions.rb
Enter fullscreen mode Exit fullscreen mode

bank_transactions テーブルで
下記のカラムを生成するマイグレーション定義。

  1. 口座番号: 文字列
  2. 金額: 少数
  3. 説明: 文字列
  4. createdAt
  5. 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
Enter fullscreen mode Exit fullscreen mode

2. seed -- 一部改善

テストデータを入れるところ。
かえでは開発で一番大事だと考えている。

db/seeds.rb
Enter fullscreen mode Exit fullscreen mode

下記のカラムに挿入される初期データ。

  1. 口座番号: 文字列
  2. 金額: 少数
  3. 説明: 文字列
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
Enter fullscreen mode Exit fullscreen mode

一番最初に全てのデータを削除する。
その後 3 レコード挿入している。
また、挿入後に結果を出力するカスタムスクリプトも入れている。

! マークは、型が違った時に適切なエラーを返す。
この場合は RecordInvalid が返ってくる。
! マークなしだと false で返ってくるので、原因の特定に時間がかかるだろう。


3. Models

app/models/bank_transaction.rb
Enter fullscreen mode Exit fullscreen mode

BankTransaction クラスに ApplicationRecord を継承させている。

class BankTransaction < ApplicationRecord
end
Enter fullscreen mode Exit fullscreen mode

ApplicationRecord とは ActiveRecord を使うためのもの。
ActiveRecord とは Rails の ORM。
ORM とはデータベースのレコードを、Rails で扱える インスタンス にするもの。

これによって、DB のテーブルを使って、

  • 1対多のアソシエーション
  • 必須やユニークのバリデーション

これらを作ることができる。
今回はまだ導入していない。


3.5 Route

まずこれを通さないと、コントローラーまで行かない。

config.route.rb を編集する。

resources :bank_transactions, only: [:index, :show]
Enter fullscreen mode Exit fullscreen mode

生成時には

  • GET ALL の index
  • GET DETAIL の show

これらのみが有効化されている。

  • CREATE
  • UPDATE
  • DELETE

これらは無効化されている。

  resources :bank_transactions, only: [:index, :show, :create, :udate, :delete]
Enter fullscreen mode Exit fullscreen mode

こうすることで有効化できる。



4. Controllers


4.0 共通メソッド

rails コマンドで生成されている。

class BankTransactionsController < ApplicationController
  before_action :set_bank_transaction, only: %i[ show update destroy ]
Enter fullscreen mode Exit fullscreen mode
  1. before_action: methodName を使うと、各 CRUD アクションが実行されたる直前に methodName が発火する
  2. 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
Enter fullscreen mode Exit fullscreen mode

引数の 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
Enter fullscreen mode Exit fullscreen mode
[
  {
    "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"
  }
]
Enter fullscreen mode Exit fullscreen mode

4.2 GET Detail

  # GET /bank_transactions/1
  def show
    render json: @bank_transaction
  end
Enter fullscreen mode Exit fullscreen mode
{
  "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"
}
Enter fullscreen mode Exit fullscreen mode

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"}%  
Enter fullscreen mode Exit fullscreen mode

すると、新しくデータができている

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
Enter fullscreen mode Exit fullscreen mode
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"
}
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode
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"
}
Enter fullscreen mode Exit fullscreen mode

4.5 DELETE (destroy)

リソースを「破壊」する。

  # DELETE /bank_transactions/1
  def destroy
    @bank_transaction.destroy
  end
Enter fullscreen mode Exit fullscreen mode
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"
}
Enter fullscreen mode Exit fullscreen mode
curl -i -X DELETE \
  -H "Content-Type: application/json" \
  http://localhost:3000/bank_transactions/23

HTTP/1.1 204 No Content
Enter fullscreen mode Exit fullscreen mode
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>",     
Enter fullscreen mode Exit fullscreen mode

Top comments (0)