1

In my model I have

field :is_open, type: Time, default: nil

However previously in this same model, I stored this type as a boolean. I now want to change it to type Time. For new items in my database this works fine, however for old records where it's still stored as a boolean, when I try to access this attribute

modelInstance.is_open

I get the following error:

#<NoMethodError: undefined method `getlocal' for true:TrueClass>

Instead of changing all the booleans in my mongo database to Time objects, is there a way/hook I can do on mongo so that when this attribute is pulled from the document, I can check if it's a boolean and replace it with a timestamp?

mu is too short
  • 426,620
  • 70
  • 833
  • 800
user2333700
  • 127
  • 1
  • 5

1 Answers1

3

You don't have to specify the field type with Mongoid. That means that you can do things like this:

class Model
  include Mongoid::Document
  field :f
end

with data like this:

> db.models.find()
{ "_id" : ObjectId(...), "f" : true }
{ "_id" : ObjectId(...), "f" : 6 }
{ "_id" : ObjectId(...), "f" : "pancakes" }

And everything will work out just fine:

rails > Model.all.map { |m| puts "#{m.f.class} - #{m.f.inspect}" }
TrueClass - true
Float - 6.0
String - "pancakes"

So you can drop the :type from your field and everything should work okay. Of course, you might want to provide your own def is_open and def is_open= methods if you need to do some sort of manual type conversion or checking while you're waiting to fix up your MongoDB data.

mu is too short
  • 426,620
  • 70
  • 833
  • 800