📝

【Raiis7】【optional: true】メモ機能を、「グループ内のみ」と「個人のみ」の両方で利用できるように設定する

2024/10/25に公開

はじめに

Rails7を用いて作成した個人開発アプリで、モデルに記載するテーブル同士のリレーションとしてbelongs_to :テーブル名, optional: trueを記載しました。
optional: trueを追記した理由と、それによってどのような機能を可能にさせるのか、下記にまとめます。

どのような課題があったか

対象のアプリのテーブル設計は下記のようになっています。
Image from Gyazo

【テーブルの説明】

  • userが特定のグループに所属すると、そのグループ内でのみメモ機能(summaryテーブル)が使えるようになる

【やりたいこと】

  • 「グループ内で使えるメモ機能」に加えて、「個人のみで使えるメモ機能」も実装したい

【解決すべき課題】

  • summaryテーブルには、外部キーであるgroup_idカラムがある
  • 「個人のみで使えるメモ機能」を使用する上では、group_idの値は不要(受け取る値がない)
  • しかし、group_idはsummaryテーブルの外部キーとして設定されているため、デフォルトではnilが許可されていない

解決策としてのoptional: true

結果として、summaryモデルには下記のような設定をしました。
belongs_to :groupの部分に、, optional: trueを追加しています。
この設定により、summaryモデルのgroup_idカラムで受け取る値がなかった場合(group_idがnilだった場合)でも、バリデーションに弾かれなくなります。

#app/models/summary.rb

class Summary < ApplicationRecord
  belongs_to :user
  belongs_to :group, optional: true

  validates :title, presence: true, length: { maximum: 255 }
  validates :content, presence: true, length: { maximum: 65_535 }
end

Railsガイドには、下記のように記載があります。

:optionalオプションにtrueを指定すると、関連付けられるオブジェクトが存在することが保証されなくなります。このオプションは、デフォルトではfalseです。

https://railsguides.jp/association_basics.html#optional:~:text=inverse_of%3A %3Abooks end-,4.1.2.11 %3Aoptional,-%3Aoptionalオプションに

今回のように、外部キーのカラムを空にした機能を実装したい時に、belongs_to :テーブル名, optional: trueは便利だと感じました。

まとめ

1つのsummaryテーブルを使って、「グループ内のみ」と「個人のみ」の両方で利用できるように設定することができました。
ただ、「グループ内で使えるメモ機能」では外部キーであるgroup_idを必須にしたいため、
optional: trueを用いてnilを許可するのはエラーが起きた時の対処を踏まえると少し懸念があると思っています。
「個人のみで使えるメモ機能」専用のsummaryテーブルを別途作成するなど、他にも方法はありそうです。
belongs_to関連付けに関しては、他にも様々なオプションが用意されているみたいなので、活用していきたいと思います。
▼belongs_to関連付けのオプション一覧
https://railsguides.jp/association_basics.html#:~:text=belongs_to関連付けでは以下のオプションがサポートされています。

参考資料

Railsガイド_Active Record の関連付け
https://railsguides.jp/association_basics.html
Railsのbelongs_toに指定できるoptional: trueとは?
https://blog.ryskit.com/entry/2018/01/27/195442

Discussion