概要
「【Rails×React】UberEats風アプリを作りながら、SPA開発を学ぼう」を使って学んでいく上で自分で勉強記録アプリを作りたいと思ったので、完成するかは置いといて、とりあえず学んだことを自分が作りたいものに置き換えて考えていく。
内容
今回作成する勉強記録アプリで使用するデータを定義する。
今回実装する内容や範囲を確認し、全体像を掴む。そこからデータの種類や名称、どのような情報を持つのか考え、押さえていく。
今回おさえたデータを入れていくデータベースの設計図がMigrationファイルと呼ばれるもの。そして、データの説明書のようなものがModelである。
例えば、記事のデータにはタイトルや内容などの情報が必要である。データベースで言えばカラムとして保持されるtitleやcontentである。このようにどんなデータベースを作って欲しいかという指示するのがRailsのMigrationである。
一方で、記事のデータそのものはどういうデータかを定義しているのはModelである。
Migrationはあくまでデータベースの箱の設計図であり、中身のデータがどういうものかを表している訳ではないことに注意。
どんなデータがあるか
今回作成するアプリケーションにおいて必要であると考えるデータは以下の通りである。
まだまだ不揃いではあると思うが、都度都度更新していこうと思う。
- ユーザ(User)
- id
- name
- password
- article_id
- 記事(Articles)
- id
- user_id
- title
- content
- status
- 成績(Score)
- id
- article_id
- score
- user_id
railsプロジェクトを作成
ここからは具体的な実装に入る。
プロジェクトを作成したいディレクトリに移動する。今回はHomeディレクトリ直下practice
ディレクトリを作成し、そこに順次作成していきたいと思う(勉強しているubereatsの内容も並行してやりたいため)。
$ mkdir practice
$ cd practice
# railsのバージョン確認
$ rails -v
Rails 7.1.2
# rubyのバージョン確認
$ ruby -v
ruby 3.0.6p216 (2023-03-30 revision 23a532679b) [x86_64-darwin22]
# railsのプロジェクトをfill_in_stockerという名前で作成
# --apiというオプションをつけることでAPIモードを意味する
$ rails new fill_in_stocker --api
rails new
が成功すればプレジェクトが完成していることがわかる。
Migrationファイルの作成
ここからはデータベースの設計書となるMigrationについて取り組んでいく。Migrationファイルは下記のようなコマンドで作成することにより、テンプレートが記述された状態のファイルを作成してくれる。
rails g
コマンドを用いてMigrationファイルを作成する。
cd fill_in_stocker
# 記事データを作成
rails g migration CreateArticles
# ユーザデータを作成
rails g migration CreateUsers
# スコアデータを作成
rails g migration CreateScores
Migrationファイルの中身を書いていく
ここからはデータベースの設計書となるMigrationファイルの中身を実際に書いていく。下記にも記すが、ここでコーディングした内容を元にデータベースが作られていく。
class CreateArticles < ActiveRecord::Migration[7.1]
def change
create_table :articles do |t|
t.references :user, null: false, foreign_key: true
t.string :name, null: false
t.string :content, null: false
t.integer :status, null: false, default: 0
t.timestamps
end
end
end
class CreateScores < ActiveRecord::Migration[7.1]
def change
create_table :scores do |t|
t.references :articles, null: false, foreign_key: true
t.references :users, null: false, foreign_key: true
t.integer :score, null: false, default: 0
t.timestamps
end
end
end
class CreateUsers < ActiveRecord::Migration[7.1]
def change
create_table :users do |t|
t.string :name, null: false
t.string :email
t.string :password, null: false
t.references :articles, foreign_key: true
t.timestamps
end
end
end
t.テーブルのカラム型 :カラム名, オプション...のように指定していく。
最後にt.timestamps
と記述することにより、自動的にcreated_at
とupdated_at
の2つのカラムを作成してくれる。
t.references :user, null: false, foreign_key: true
のように書くことでUserモデルと紐づけることができ、user_id
というカラムがArticleテーブルに生成される。
またdefault: 0
と付けることでデフォルトで0が入るよう設定できる。
db:migrate
を実行する
以下のコードを実行することでmigrationファイルを元にmigrationが実行されテーブルが作成される。
$ bundle exec rails db:migrate
migrationが完了すると、db/migrate/schema.rb
というファイルが作成されるため、これは直接編集しないようにする。
作成されたschema.rbがこちらです。
ActiveRecord::Schema[7.1].define(version: 2023_11_24_180726) do
create_table "articles", force: :cascade do |t|
t.integer "user_id", null: false
t.string "name", null: false
t.string "content", null: false
t.integer "status", default: 0, null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["user_id"], name: "index_articles_on_user_id"
end
create_table "scores", force: :cascade do |t|
t.integer "articles_id", null: false
t.integer "users_id", null: false
t.integer "score", default: 0, null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["articles_id"], name: "index_scores_on_articles_id"
t.index ["users_id"], name: "index_scores_on_users_id"
end
create_table "users", force: :cascade do |t|
t.string "name", null: false
t.string "email"
t.string "password", null: false
t.integer "articles_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["articles_id"], name: "index_users_on_articles_id"
end
add_foreign_key "articles", "users"
add_foreign_key "scores", "articles", column: "articles_id"
add_foreign_key "scores", "users", column: "users_id"
add_foreign_key "users", "articles", column: "articles_id"
end
Modelファイルを作成
ここでは、データの説明書となるModelファイルを作成していく。
プロジェクト直下に戻り、touchコマンドを用いてファイルを作成する。
$ pwd
/Users/ooooooo/practice/fill_in_stocker
$ touch app/models/article.rb
$ touch app/models/user.rb
$ touch app/models/score.rb
学習サイトを元に書いてみたが、ものすごく不十分だと思うため、今後必要があれば増やしていきたいと思う。
初めから考えても埒が明かない気がするので💦
一応今回記述したmodelファイルは以下の通りである。
class Article < ApplicationRecord
belongs_to :user
validates :title, length: { maximum: 30 }
enum status: { inactive: 0, active: 1 }
end
class User < ApplicationRecord
has_many :article
validates :name, presence: true, length: { maximum: 30 }
validates :password, presence: true
end
class Score < ApplicationRecord
belongs_to :article
end
今回modelファイルを書いていて、データベースの設定上以下2点について違和感を感じたので修正しました!
今回は特にレコードを作成していなかったので、データベースを作り直す形で修正しました。
- articleモデルのnameカラム → titleカラム
- scoreモデルにuserモデルを紐づけていたがuserから参照する動線がおかしいと考えたため削除
上記にも記したが、今回はレコードがない状態であったので、create_ooooといったmigrationファイルを修正してデータベースを作り直した。
本来であれば、修正するためのmigrationファイルを作成した上でmigrateを実行しデータベースを修正する。
ただ不要なファイルを増やしたくないというのとレコードがない状態であったので、そもそものファイルを修正し作り直す。
class CreateArticles < ActiveRecord::Migration[7.1]
def change
create_table :articles do |t|
t.references :user, null: false, foreign_key: true
# name → title
# t.string :name, null: false
t.string :title, null: false
t.string :content, null: false
t.integer :status, null: false, default: 0
t.timestamps
end
end
end
class CreateScores < ActiveRecord::Migration[7.1]
def change
create_table :scores do |t|
t.references :articles, null: false, foreign_key: true
# この行を削除
# t.references :users, null: false, foreign_key: true
t.integer :score, null: false, default: 0
t.timestamps
end
end
end
# 修正が完了したら以下コマンドで作り直す
$ rails db:migrate:reset
参考記事
- 【Rails×React】UberEats風アプリを作りながら、SPA開発を学ぼう
- Zenn「Rails】Enumを使いこなそう」
- Qiita「Rails:migrateでDBをリセットして最初からつくり直す方法。」