はじめに
アプリ制作の過程で、ポリモーフィック関連を用いた実装を行いました。ここではその実装過程で得られた気づきをまとめます。ポリモーフィック関連について実際の例を交えながらなるべく分かりやすくまとめたいと思います。
なぜポリモーフィック関連付けが便利なのか
例えば、ブログ記事にコメントを付ける機能を作ったとします。その後、イベントページにもコメントを付けたくなったとします。通常であれば、新しくコードを書き足さないといけないと思います。しかし、ポリモーフィック関連付けを使うと、既存のコードをほとんど変更せずに、イベントにもコメントを付けられるようになります。
それでは、実際にコードを見ていきましょう。
モデルの設定
まず、モデルの設定から。Article
、Event
、Comment
の3つのモデルを作ります。
class Article < ApplicationRecord
has_many :comments, as: :commentable
end
class Event < ApplicationRecord
has_many :comments, as: :commentable
end
class Comment < ApplicationRecord
belongs_to :commentable, polymorphic: true
end
class Game < ApplicationRecord
belongs_to :home_teamable, polymorphic: true
belongs_to :away_teamable, polymorphic: true
end
ここでのポイントは、Article
とEvent
にhas_many :comments, as: :commentable
と書いているところです。
これで「コメント可能な」オブジェクトとして定義されます。Comment
モデルのbelongs_to :commentable, polymorphic: true
も重要です。これで、Comment
がArticle
とEvent
にも紐付けられるようになります。
テーブルの定義
次に、テーブルの設定です。マイグレーションファイルを作成して、必要なテーブルを作ります。
class CreateComments < ActiveRecord::Migration[6.1]
def change
create_table :comments do |t|
t.text :content, null: false
t.references :commentable, polymorphic: true, index: true
t.timestamps
end
end
end
ここで常用なのは、t.references :commentable, polymorphic: true
の部分です。これによって、comments
テーブルにcommentable_type
とcommentable_id
というカラムが追加されます。これらのカラムを使って、コメントがArticle
に属しているのか、Event
に属しているのかを判断することができます。
ビューの設定
最後に、ビューの例も見てみましょう。
<%= form_with(model: [ @commentable, @comment ], local: true) do |form| %>
<div class="field">
<%= form.label :content, 'コメント' %>
<%= form.text_area :content %>
</div>
<div class="actions">
<%= form.submit '投稿する' %>
</div>
<% end %>
このフォームは、Article
ページとEvent
ページで使えます。@commentable
の中身が自動的に判断されるので、同じフォームで両方に対応することができます。
まとめ
ポリモーフィック関連付けを使うとかなりスマートにコードを書くことだできます。僕自身まだまだ使いこなせておらず少し難しく感じる部分もありますが、使いこなせるようになるとコードの可読性と拡張性が大幅に向上するはずです。