LoginSignup
2
2

More than 5 years have passed since last update.

Mongoid6のモデルでRegexpを使うと妙なことが起きる

Posted at

Mongoidを使っているRailsアプリを、Rails4から5にあげるときに奇妙なことが起きた。
Rails4から5にあげるのに伴って、Mongoidを5.xから6.xに更新したのだが、テストが通らなくなった。

問題の箇所を抜粋すると以下のようなコードになる。

my_model.rb
class MyModel
  include Mongoid::Document
  field :key, type: String
  field :default, type: String
  field :format, type: String

  validates :key, presence: true, uniqueness: true, format: {with: /\A\w+\z/}
  validate :default_value_conform_to_format

  private
  def default_value_conform_to_format
    regexp = Regexp.new(self.format.to_s)
    unless regexp =~ self.default.to_s
      errors.add(:default, "does not match regexp #{self.format}")
    end
  end
end

Mongoidを6にあげるとdefault_value_conform_to_formatでvalidationエラーが発生するようになる。
ちなみにテストケースでは、defaultformatもどちらもnilになっている。
空の正規表現は、空文字列にマッチするはずなので、エラーが起きるはずはないと思っていた。

// =~ ""  #=> 0

問題となっていたのは、実はRubyの標準ライブラリのRegexpではなくて、Mongoidの中のMongoid::Matchable::Regexpというクラスを参照するように変わってしまっていたことだった。
どうやらMongoidが勝手にこのような名前のクラスを追加してしまっていたようだ。しかもタチの悪いことに標準のRegexpと挙動が異なる。

-    regexp = Regexp.new(self.format.to_s)
+    regexp = ::Regexp.new(self.format.to_s)

としたところ解決した。

2
2
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
2