Railsのポリモーフィック関連付けについて

ポリモーフィックとは

1つのモデルが他の複数のモデルに属していることを、1つの関連付けだけで表現できます。

一つのモデルを同じインターフェースを持ったものが扱う(ダックタイピングする)

ポリモーフィックとは1つのモデルで関連付いた複数のモデルの処理を共通化することです。

実装例

例) 本(Book)、日報(Report)からコメント(Comment)を作成する

ポリモーフィックなCommentモデルを作成する

ポリモーフィック用でcommentable カラムを追加する

$ rails g model Comment commentable:references{polymorphic}

上記コマンドでポリモーフィックに必要な以下の2つのカラムが作成される

# schema.rb
...
create_table "comments", force: :cascade do |t|
  t.string "commentable_type", null: false #ポリモーフィック用カラム
  t.integer "commentable_id", null: false #ポリモーフィック用カラム
  t.datetime "created_at", precision: 6, null: false
  t.datetime "updated_at", precision: 6, null: false
  t.index ["commentable_type", "commentable_id"], name: "index_comments_on_commentable"
end

関連付け

rails db:migrate 後に以下の関連付けを行う

  • 子モデルCommentにはbelongs_to は自動付与される
  • 親モデルBook、Reportにはhas_many は自動付与されない(手動での付与が必要)
# book.rb
class Book < ApplicationRecord
  has_many :comments, as: :commentable
end

# report.rb
class Report < ApplicationRecord
  has_many :comments, as: :commentable
end

# comment.rb
class Comment < ApplicationRecord
  belongs_to :commentable, polymorphic: true
end

railsコンソールで操作してみる

# ReportからCommentを作成
> report = Report.first
> report.comments.create
=> #<Comment:... id: nil, commentable_type: "Report", commentable_id: 1, created_at: nil, updated_at: nil>

# BookからCommentを作成
> book = Book.first
> book.comments.create
=> #<Comment:... id: nil, commentable_type: "Book", commentable_id: 2, created_at: nil, updated_at: nil>
  • commentable_type にはポリモーフィックで関連付けられたモデル名が入る
  • commentable_id には関連付けられた親モデルのIDが入る

感想

前に調査した際のメモが残っていたのでもったいないので記事にしてみたシリーズ第一弾(笑) 絶対忘れる未来の自分の為にたくさん記事にしていこう。

参照

Active Record の関連付け - Railsガイド

Railsのポリモーフィック関連とはなんなのか - Qiita

Railsのポリモーフィック関連 初心者→中級者へのSTEP10/25 - Qiita

Railsのポリモーフィックでのform_with - karlley