第2のモデルを追加する: 小林研 Rails Tips (63)

このページの内容は以下のリポジトリに1日遅れで反映されます(記事執筆前に前日分をコミットしています)。

https://github.com/hkob/hkob_blog

はじめに

Rails Tips の 63 回目です。第二のモデルである Comment モデルを追加してみます。

Rails をはじめよう - Railsガイド

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 ファイルは以下のようになっています。commenterbody には 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"

おわりに

データベースのマイグレーションまで実施したので、明日は実際に属性に関するテストを実施していきます。