2
0

【Rails】ポリモーフィックが便利〜

Last updated at Posted at 2023-11-24

どうもこんにちは。

今回はポリモーフィックについてまとめます。

ポリモーフィックってなんぞや?

ポリモーフィックとは、複数のモデル同士の関連付けの考え方です。

この考え方は、異なるモデルを単一の関連で扱う機能です。

例えば、以下のようにテーブルが存在しているとします。

commentsテーブル

カラム名 値1 値2 値3
id integer 1 2 3
comment text ワンちゃんかわいい!! よろしくお願いします。 この時期寒くね?
article_id integer null 1 null
photo_id integer 2 null null
tweet_id integer null null 1

articlesテーブル

カラム名 値1 値2
id integer 1 2
article_title string 私の自己紹介 私の会社について

photosテーブル

カラム名 値1 値2
id integer 1 2
photo_title string 山からの景色 飼っているペットの写真

tweetsテーブル

カラム名 値1 値2
id integer 1 2
tweet_title string 海なう 美味しいご飯なう

このような状態だと、commentsテーブルではarticle_idに値が入っているときにphoto_idtweet_idnullになってしまっていますね。

デメリット

データベースの容量の無駄

上記のようにデータベースを作成してしまうと、無駄なカラムが出現してしまい、無駄に容量を使用してしまいます。
これは、データベース使用料などのコストがかかってしまうことに繋がってしまいます。

拡張性の欠如

上記のデータベースだと、記事,写真,ツイート以外のものに対してコメントできるようになった場合、カラムを増やなければなりません。

これもデータベースの容量の無駄に繋がってしまいますね。。。

データの整合性

article_idカラム,photo_idカラム,tweet_idカラム全てに値が入っていたり、全てに値が入っていなかったりする可能性があります。

この場合、チェックする機構を作ればいい話ですが、ポリモーフィックを導入するとこのチェックする機構が必要なくなります。

ポリモーフィックを導入するとどうなる?

Commentテーブルは以下のようになります。

commentsテーブル

カラム名 値1 値2 値3
id integer 1 2 3
comment text ワンちゃんかわいい!! よろしくお願いします。 この時期寒くね?
commentable_type string Photo Article Tweet
commentable_id integer 2 1 1

nullがなくなってカラムも減ります!

では実際に実装してみましょう。

実装手順

手順1. Commentテーブルを作成する

以下のコマンドでマイグレーションファイルを作成する。

rails g migration CreateCommentTable

以下のようにマイグレーションファイルを編集します。

create_table :comments do |t|
  t.string :content
  t.references :commentable, polymorphic: true, index: true
  t.timestamps
end

手順2. Commentモデルに設定する

class Comment < ApplicationRecord
  belongs_to :commentable, polymorphic: true
end

手順3. 関連させたいモデルに設定する

class Article < ApplicationRecord
  has_many :comments, as: :commentable
end
class Photo < ApplicationRecord
  has_many :comments, as: :commentable
end
class Event < ApplicationRecord
  has_many :comments, as: :commentable
end

手順4. コントローラに処理を記述

class ArticlesController < ApplicationController
    before_action :set_article, only: %i[comment_create]
    
    def comment_create
        @comment = Comment.new(comment_params)
        @comment.commentable_type = 'Article'
        @comment.commentable_id = @article.id
        if @comment.save
            redirect_to articles_path
        else
            render :new
        end
    end
    
    private

    def set_article
        @article = Article.find(params[:id])
    end
    
    def comment_params
        params.require(:comment).permit(:comment)
    end
end

Photo,Tweetのコントローラに対しても同様にコードを記述すればOKです!

うまくやれば、Commentsコントローラに一括で実装できます!

まとめ

ポリモーフィックはデータベース使用料などのコストを抑えるなどの目的のために実装すべき仕組みだと思います。

以上

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0