カクカクしかじか

技術的なアレコレ

Railsアプリでmongoidを使った場合の特定フィールドに対するユニークバリデーションの実装方法

概要

RailsでMongoDB用のORMとして mongoid というgemがあります。
ここではそれを使った場合のモデルのバリデーションについてまとめてみます。

注意

RDBで言うカラムのことをMongoDBではフィールドと呼びます。 後述するフィールドは頭の中でカラムと変換すれば大丈夫です。

検証環境

Railsのバージョン:4.2.9
gem 'mongoid' のバージョン:5.4.0
MongoDBのバージョン:3.2

具体例

GroupモデルとUserモデルが一対多の関係であり、その中でGroupに対するUserのemailは一意であることをチェックするバリデーションを例にしてみます。(実際はUserもGroupを複数持つ形の多対多の関係になることが多いと思いますが...ここでは一旦、一対多で話を進めます)

user.rb

# Userモデル
belongs_to :group

group.rb

# Groupモデル
has_many :users

実装方法

  • uniquenessで一意指定
  • uniquenessに加えてアソシエーションを組んでいるモデルのidフィールドを指定

特定のモデルに対して、アソシエーションが絡んだ形で一意を保証する場合は、 scope を使います。

# Userモデル
validates :email, uniqueness: { scope: [:group_id] }

おまけ:特定のフィールドの値が存在する場合のみバリデーションをかける場合

とあるコミュニティグループに対してfacebookで会員登録をする場合にgroup_idに対するfacebook_idが一意かどうかをチェックしたい場合(例が雑かも...)

user.rb

# Userモデル
validates :facebook_id, uniqueness: { scope: [:group_id] }, if: -> { facebook_id.present? }