Agenda
概要
Rails APIで立ち上げるまでにやること一覧。
事前準備
json-server で、DB構造を設計しておく。
db.sjonの中身は冗長的に書く(リレーション張れないため)。
例
{
"users": [
{
"id": 1,
"wallet_address": "HXtBm8XZbxaTt41uqaKhwUAa6Z1aPyvJdsZVENiWsetg"
},
{
"id": 2,
"wallet_address": "5U3bH5b6XtG99aVWLqwVzYPVpQiFHytBD68Rz2eFPZd7"
}
],
"products": [
{
"id": 1,
"barcode": "45019517",
"name": "ポカリスエット ペットボトル(500mL)"
},
{
"id": 2,
"barcode": "4901777018686",
"name": "サントリー天然水 2Lペット"
}
],
"characters": [
{
"id": 1,
"product_id": 1,
"name": "ポカリスエットン",
"total_rarity": 1,
"image": "https://bafybeibvl5c2j3izinxxukzjidnuvlf66qviheb7yrqxo2eefvok7ntqdq.ipfs.dweb.link/791.gif"
},
{
"id": 2,
"product_id": 2,
"name": "天然水神様",
"total_rarity": 2,
"image": "https://bafybeibikwgxr6d3zp33rsh4iguvoylxrebhlri72g24g445ohanfnkoqe.ipfs.dweb.link/147.gif"
}
],
"scan_histories": [
{
"id": 1,
"timestamp": "1655084185",
"wallet_address": "HXtBm8XZbxaTt41uqaKhwUAa6Z1aPyvJdsZVENiWsetg",
"barcode": "45019517",
"characters": {
"name": "いろはスケル",
"image": "https://bafybeibvl5c2j3izinxxukzjidnuvlf66qviheb7yrqxo2eefvok7ntqdq.ipfs.dweb.link/791.gif"
},
"mint_histories": {
"mint_address": "XtBt31GCF5enFg7YG1YkH33Y5w1SruGMcz7GttUVUpH"
}
},
{
"id": 2,
"timestamp": "1655175600",
"wallet_address": "HXtBm8XZbxaTt41uqaKhwUAa6Z1aPyvJdsZVENiWsetg",
"barcode": "4901777018686",
"characters": {
"name": "天然水神様",
"image": "https://bafybeibikwgxr6d3zp33rsh4iguvoylxrebhlri72g24g445ohanfnkoqe.ipfs.dweb.link/147.gif"
}
}
],
"deposit_histories": [
{
"id": 1,
"scan_history_id": 1,
"timestamp": "1655084185",
"tx_id": "",
"tx_status": "success"
}
],
"mint_histories": [
{
"id": 1,
"scan_history_id": 1,
"timestamp": "1655084185",
"mint_address": "XtBt31GCF5enFg7YG1YkH33Y5w1SruGMcz7GttUVUpH",
"tx_status": "success"
}
]
}
ステップ
Rails API作成
% rails new <アプリ名> --api
Gem用意
ポイントは、jbuilderとrack-corsをアクティブにすること。
jbuilderはview側でJSONを自由に書けて、rack-corsはクロスドメイン対応で必要。
Gemfile
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby "3.1.2"
gem "rails", "~> 7.0.3"
gem "sqlite3", "~> 1.4"
gem "puma", "~> 5.0"
gem "jbuilder"
gem "tzinfo-data", platforms: %i[ mingw mswin x64_mingw jruby ]
gem "bootsnap", require: false
gem "rack-cors"
group :development, :test do
gem "debug", platforms: %i[ mri mingw x64_mingw ]
end
group :development do
gem "spring"
end
Gemをインストール
% bundle install --path vendor/bundle
Scaffold
json-serverの骨子をもとに、scaffoldで、MVCの雛形を作る。
% rails g scaffold <モデル名> <カラム名:型>
% rails db:migrate
リレーションを張る場合(外部参照キー)は、「モデル名:references」を記述。
(例)user:references (user_id:referencesではない)
CORS設定
クロスドメイン対応で、暫定的に全許可設定。
config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins "*"
resource "*",
headers: :any,
methods: [:get, :post, :put, :patch, :delete, :options, :head]
end
end
脆弱なため、本番リリース前にはちゃんとした設定が必要。
Rails API起動
% rails s -p <ポート番号>
メモ
render json
Controllerで「render json」するとViewは読み込まれず、Controller側で制御して出力される。「View名.json.jbuilder」のファイルを作っても無視される。
render json: @mint_history
「View名.json.jbuilder」のファイルは、Controller側で「@変数名」で渡せば、View側で自由に扱える。
Controllerのshowに記述がないのに動く
デフォルトだと、before_actionでfindがセットされているため。
以下のような記述。
before_action :set_mint_history, only: %i[ show update destroy ]
〜〜〜
def set_mint_history
@mint_history = MintHistory.find(params[:id])
end
references(外部参照キー)に後追いでunique設定
scaffoldでreferences設定したあとに、unique設定したい場合。
マイグレーションするときに、「add_index」でuniqeu設定すると、indexありますというエラーが出る。
% rails db:migrate
〜〜〜
ActiveRecord::StatementInvalid: SQLite3::SQLException: "index" already exists
これは、まずindexを削除してから、あらためてindex設定すればOK(remove_indexを先に書いてadd_indexを書く)。
class ChangeColumnOnMintHistory < ActiveRecord::Migration[7.0]
def change
remove_index :mint_histories, column: :scan_history_id
add_index :mint_histories, :scan_history_id, unique: true
end
end