RailsではMVCアーキテクチャ(設計思想)を採用しています。
MVCはModel 、View、Controllerの頭文字から来ています。
このLessonではModelについて学習していきましょう。
Model(モデル)とは操作する対象(resource)です。Railsアプリでデータベースに登録したり、データベースの内容を変更したり、削除するのはモデルを使って操作していきます。
モデルはオブジェクト指向のClassになります。今回は投稿のモデルPostを作り、データベースを操作していきます。
ではboardのディレクトリにいることを確認してPostモデルを作成していきましょう。
Postモデルは投稿を保存するためのcontentというstring(文字列)型のフィールド(属性)をもつようにします。
構文は以下のようになります。
$ rails g model モデル名 属性1:カラム型 , 属性2:カラム型, 属性3:カラム型…
尚、カラム型がstringの場合、省略することができることも覚えておきましょう。以下コマンドを実行してモデルを作成してください。
$ pwd
/xxx/xxxx/xxx/board
$ rails g model Post content
「g」 は 「generate」の省略形です。以下コマンドも同じ動作になります。
$ rails genelate model Post content
さらに以下も同じです。
$ rails genelate model Post content:string
以下のようになりましたでしょうか?
invoke active_record
create db/migrate/20221208001031_create_posts.rb
create app/models/post.rb
createの行が自動で生成されたファイルです。以下2つのファイルが作られていることがわかりますね。
もしモデルの名称などを間違ってしまった場合は自動生成されたものを削除してくれる以下コマンドを使いましょう。
$ rails d model Post
「d」 は 「destroy」の省略形です。以下コマンドも同じ動作になります。
$ rails destroy model Post
こちらのコマンドを実行すると自動生成されたファイルが全て削除されます。
ではapp/models/post.rbファイルを見てみましょう。
class Post < ApplicationRecord
end
これはPostというクラスになっています。このPostクラスこそがModelになるのです。ここで必ず覚えてほしい注意点があります。それは
ということです。これはルールとして必ず覚えてください。オブジェクト指向を学んだ方はわかると思いますが、クラスということはクラスメソッドやインスタンスメソッドを記載し使用することができるということになります。
rubyではクラスは必ず先頭が大文字になります。厳密に言いますとアッパーキャメルケース(UpperCamelCase)という記法になります。これは単語の先頭が大文字になる記法です。また、必ず単数形でなければいけません。
$ rails g model post content
$ rails g model Post content
$ rails g model posts content
複数形でモデルを作成しようとしても自動的に単数形になります(一般的な単語の場合)。次にdb/migrate/xxxxxxxxxxx_create_posts.rbファイルを見ていきましょう。xxxxxxxxxxx部分は作成した日時になっていると思います。このファイルはマイグレーションファイルと呼ばれます。
このマイグレーションファイルは各SQL-DATABASEのSchemaを変更するためのdb/schema.rbを書き換えるファイルです。マイグレーションファイルを作成しただけではDBの変更は行われません。マイグレーションの実行をするとschema.rbが変更され、データベースのschemaも変更されます。
Schema(スキーマ)とはデータベースの構造を表したファイルの事を言います。SQL-Databaseには必ずこの構造を示したSchemaがあります。railsアプリには 「db/schema.rb」ファイルが後述する最初のマイグレーションの実行時に作成され、その後マイグレーションファイルを実行するたびにこのファイルが書き換わります。 schema.rbは使用するDatabaseに対応するGemによってDatabaseサーバのSchemaを書き換えます。マイグレーションの実行によってデータベースの構造を書き換えることができるのです。
データベースによって自動的に適切なスキーマを生成するので、プログラミングする際にデータベースの違いを意識することはほとんどありません。
ではマイグレーションファイルを確認してみましょう。db/migrate/xxxxxxxxxxx_create_posts.rbファイルを開いてください。
class CreatePosts < ActiveRecord::Migration[7.0]
def change
create_table :posts do |t|
t.string :content
t.timestamps
end
end
end
create_table :posts の行がpostsテーブルを作成する記述です。
t.string :contentではcontentカラムをstring型(文字列型)で作成します。
最後にt.timestampsの行でcreated_at(作成日)カラムと(update_at)カラムを作成しています。
また、Railsアプリでは自動的に必ずidカラムが主キー(PrimaryKey)として作成されるルールになっています。
それではマイグレーションファイルを実行しましょう。
$ rails db:migrate
マイグレーションファイルに問題が無いと以下のようなメッセージが出ます。
== xxxxxxxxxxxx CreatePosts: migrating ======================================
-- create_table(:posts)
-> 0.0130s
== xxxxxxxxxxxx CreatePosts: migrated (0.0130s) =============================
xxxxxxxxxxxxの部分はマイグレーションファイルの日付になります。皆さんの作成したファイルと同じ日時になっているはずです。
「create_table(:posts)」のところでpostsテーブルを作成しているのがわかります。
そして CreatePosts: migrated のように 「migrated」が出たらマイグレーションの実行が無事完了です。
PostgreSQLクライアントに接続して正しくDBが作成されているかを確認しましょう。
$ psql board_development
board_development=> \d posts
Table "public.posts"
Column | Type | Collation | Nullable | Default
------------+--------------------------------+-----------+----------+-----------------------------------
id | bigint | | not null | nextval('posts_id_seq'::regclass)
content | character varying | | |
created_at | timestamp(6) without time zone | | not null |
updated_at | timestamp(6) without time zone | | not null |
Indexes:
"posts_pkey" PRIMARY KEY, btree (id)
board_development=> quit
上述していましたが、マイグレーションファイルには特に見当たらなかったidカラムがPrimarykeyとして作成されていますね。
そしてstringを指定していたcontentカラムは varchar(255)の型になっています。
timestampの記載によってcreatd_atカラムとupdated_atカラムがdatetime型で作成されました。
慣れるまではこのようにPostgreSQLクライアントで確認してどのようなカラムができてるかを確認していくと良いです。
以前、マイグレーションの実行はschema.rbを書き換えるものだと説明しました。こちらも確認しておきましょう。db/schema.rbファイルを開いてください。(コメントアウト部分は省いています。)
ActiveRecord::Schema[7.0].define(version: 20yy_mm_dd_xxxxxx) do
enable_extension "plpgsql"
create_table "posts", force: :cascade do |t|
t.string "content"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
このようにDBの構造が記されています。
schema.rbでも確認できるようになっておくと良いでしょう。
db/schema.rb ファイルはマイグレーションの実行によって書き換わるため、こちらのファイルを編集しても意味がありません。Railsではデータベースの構造を変えるには全てマイグレーションファイルで行います。
このLessonではここまでModelを作成し、マイグレーションファイルを実行しました。
モデルとテーブルは密接な関係にあります。
ここでぜひ覚えておいてほしい事は 「テーブルの名前はモデルの複数形、全て小文字」であることです。
Fooというモデルに関連するのはFoosテーブルになります。この命名ルールに則るとコードを短く読みやすい状態(可読性の高いコード)にすることができます。
マイグレーションの実行を行うと、その実行済みのマイグレーションファイルは編集しても無視されてしまいます。とても重要なことなので必ず覚えておきましょう。
ではマイグレーションを実行した後に間違いに気づき、マイグレーションファイルを修正したいといったときはどうすれば良いでしょう。
そういった時にはこのチャプターを参考にしてください。
ただし、マイグレーションをやり直すという事はそのマイグレーションファイルで作成したテーブルやカラムのレコードは消えてしまいます。データが消えてしまっては困る本番環境では特に慎重に行う必要がありますし、サービス提供後は極力するべきではありません。
まずマイグレーションが実行されているかどうかを確認しましょう。
$ rails db:migrate:status
database: board_development
Status Migration ID Migration Name
--------------------------------------------------
up 20xx0101111111 Create posts
statusが up になっているのは実行済みのマイグレーションファイルです。 IDとNameでどのファイルか特定できますね。もし複数のマイグレーションファイルがあった場合は実行順に表示されます。実行順番は日付の古い順になります。日付順に実行されるということも重要なポイントです。
では20xx0101111111_create_posts.rbは実行済みなので、実行前に戻して編集しましょう。以下コマンドでマイグレーションの実行をひとつ前に戻すことができます。
$ rails db:rollback
以下のようになりましたか?
== 20xx0101111111 CreatePosts: reverting ======================================
-- drop_table(:posts)
-> 0.0392s
== 20xx0101111111 CreatePosts: reverted (0.0555s) =============================
create_postsの内容はpostsテーブルを作成するものだったので、これを打ち消す操作が自動的に行われます。テーブルの削除ですね。「drop_table(:posts)」の表示が出ているのを確認しておきましょう。
ではここでもう一度ステータスを確認しましょう。
$rails db:migrate:status
Status Migration ID Migration Name
--------------------------------------------------
down 20yymmddxxxxxx Create posts
statusがdownになりましたね!マイグレーションが実行前だという事を示しています。
ではPostgreSQLクライアントでも確認してみてください。
$ psql -d board_development
board_development=> \dt
postsテーブルがなくなっているのが確認できましたか?これでマイグレーションファイルの編集ができます。間違っていた部分を修正し、修正ができたらマイグレーションの実行を行ってください。
$ rails db:migrate
エラーなく実行できましたか?
PostgreSQLクライアントに接続して正しく変更ができたことも確認しておきましょう。
ロールバックのコマンドは一段階前に戻すものでした「n回前」に戻す場合には以下コマンドを実行しましょう。
$ rails db:rollback STEP=n
ここまでモデルとマイグレーションファイルについて学習してきました。
マイグレーションファイルの役割と概要を確認しておきましょう。
主なコマンドコマンド | 意味 |
---|---|
rails db:create | データベース作成 |
rails db:drop | データベースの削除 |
rails db:migrate | マイグレーションの実行 |
rails db:migrate:status | マイグレーション実行状況の確認 |
rails db:rollback | マイグレーションを1段階前に戻す |