このページの内容は以下のリポジトリに1日遅れで反映されます(記事執筆前に前日分をコミットしています)。
https://github.com/hkob/hkob_blog
はじめに
Rails Tips の 63 回目です。第二のモデルである Comment モデルを追加してみます。
8.1 第2のモデルを追加する
Rails ガイドでは、Article モデルへの参照を保持する Comment モデルを作成しています。私が Rails を始めた頃は references などはなく、article_id を作成し、自分で index を作成していましたが、今は便利なものがあるのですね。
$ bin/rails g model comment commenter:string body:text article:references invoke active_record create db/migrate/20240131125824_create_comments.rb create app/models/comment.rb invoke rspec create spec/models/comment_spec.rb
migration ファイルは以下のようになっています。commenter
と body
には null: false
を追加しました。
class CreateComments < ActiveRecord::Migration[7.1] def change create_table :comments do |t| t.string :commenter, null: false t.text :body, null: false t.references :article, null: false, foreign_key: true t.timestamps end end end
development と test の両方で migration を実行します。
$ bin/rails db:migrate == 20240131125824 CreateComments: migrating =================================== -- create_table(:comments) -> 0.0296s == 20240131125824 CreateComments: migrated (0.0297s) ========================== $ bin/rails db:migrate RAILS_ENV=test == 20240131125824 CreateComments: migrating =================================== -- create_table(:comments) -> 0.0156s == 20240131125824 CreateComments: migrated (0.0157s) ==========================
references で何が行われるのかは db/schema.rb を確認するとわかります。手動で記述していた article_id
による index
が自動で設定されています。また、foreign_key: true
を入れてあるので、外部キー制約も付いています。このため、comments
は関連する article
が必ず存在する必要があり、comments
が全て削除されない限りarticle
は削除できなくなります。
create_table "comments", force: :cascade do |t| t.string "commenter", null: false t.text "body", null: false t.bigint "article_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["article_id"], name: "index_comments_on_article_id" end add_foreign_key "comments", "articles"
おわりに
データベースのマイグレーションまで実施したので、明日は実際に属性に関するテストを実施していきます。