Mongoid で Custom field serialization を適用して Uniqueness validation を機能させる

  • 1
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

MongoDB は 8 bit Integer 以上は扱えないようでして, でも Ruby での Bignum を格納したいという要件がありました.

最初は元から定義してある BigDecimal type を使っていたのですが, これがあまり良くなくて MongoDB フレンドリーな形式にする時(serialize 時?) に NoMethodError: __bson_dump__ でおちてくれるのです.

なので独自タイプを作ってみました.

class User
  include Mongoid::Document
  field :uid, type: Bignum
end
module Mongoid::Extensions
  module Bignum
    def mongoize
      to_s
    end

    module ClassMethods
      def mongoize(obj)
        obj.to_s
      end

      def demongoize(obj)
        obj.to_i
      end

      alias :evolve :mongoize
    end
  end
end

::Bignum.__send__(:include, Mongoid::Extensions::Bignum)
::Bignum.__send__(:extend, Mongoid::Extensions::Bignum::ClassMethods)

順調に Examples をパスしたのですが uniqueness の Validation でうまく mongoize してくれなくて 8-bit int のエラーがでてしまっていました.

そこで組み込みがダメなら, と自作 validation で対応することにしました.

  validate :uniqueness_of_uid

  def uniqueness_of_uid
    errors.add(:unique_uid, "uid: #{uid} is not unique.") if self.class.where(uid: uid).count > 0
  end

とりあえずこれでしのげたけど, 組み込みの validate_uniqueness_of がうまく動かない原因もコード読んで探ってつきとめれればイイナー