1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

勉強記録ウェブアプリ作成の軌跡 1:データ・モデルの設計

Last updated at Posted at 2023-11-25

概要

「【Rails×React】UberEats風アプリを作りながら、SPA開発を学ぼう」を使って学んでいく上で自分で勉強記録アプリを作りたいと思ったので、完成するかは置いといて、とりあえず学んだことを自分が作りたいものに置き換えて考えていく。

内容

今回作成する勉強記録アプリで使用するデータを定義する。
今回実装する内容や範囲を確認し、全体像を掴む。そこからデータの種類や名称、どのような情報を持つのか考え、押さえていく。
今回おさえたデータを入れていくデータベースの設計図がMigrationファイルと呼ばれるもの。そして、データの説明書のようなものがModelである。

例えば、記事のデータにはタイトルや内容などの情報が必要である。データベースで言えばカラムとして保持されるtitleやcontentである。このようにどんなデータベースを作って欲しいかという指示するのがRailsのMigrationである。

一方で、記事のデータそのものはどういうデータかを定義しているのはModelである。

Migrationはあくまでデータベースの箱の設計図であり、中身のデータがどういうものかを表している訳ではないことに注意。

どんなデータがあるか

今回作成するアプリケーションにおいて必要であると考えるデータは以下の通りである。
まだまだ不揃いではあると思うが、都度都度更新していこうと思う。

  • ユーザ(User)
    • id
    • name
    • email
    • 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ファイルの中身を実際に書いていく。下記にも記すが、ここでコーディングした内容を元にデータベースが作られていく。

oooooooooooooo_create_articles.rb
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
oooooooooooooo_create_scores.rb
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
oooooooooooooo_create_users.rb
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_atupdated_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がこちらです。

db/migrate/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ファイルは以下の通りである。

app/models/article.rb
class Article < ApplicationRecord
  belongs_to :user

  validates :title, length: { maximum: 30 }

  enum status: { inactive: 0, active: 1 }
end
app/models/user.rb
class User < ApplicationRecord
  has_many :article

  validates :name, presence: true, length: { maximum: 30 }
  validates :password, presence: true
end
app/models/score.rb
class Score < ApplicationRecord
  belongs_to :article

end

今回modelファイルを書いていて、データベースの設定上以下2点について違和感を感じたので修正しました!
今回は特にレコードを作成していなかったので、データベースを作り直す形で修正しました。

  • articleモデルのnameカラム → titleカラム
  • scoreモデルにuserモデルを紐づけていたがuserから参照する動線がおかしいと考えたため削除

上記にも記したが、今回はレコードがない状態であったので、create_ooooといったmigrationファイルを修正してデータベースを作り直した。
本来であれば、修正するためのmigrationファイルを作成した上でmigrateを実行しデータベースを修正する。
ただ不要なファイルを増やしたくないというのとレコードがない状態であったので、そもそものファイルを修正し作り直す。

oooooooooooooo_create_articles.rb
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
oooooooooooooo_create_scores.rb
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

参考記事

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?