I'm building a new project with Rails 7 and MongoDB 8. And I wanted to use enumerators for multiple fields ( states etc .. )
I wanted to use the gem mongoid-enum but it doesn't work with Mongo 8.
Is switching to SQL database a solution ? Or is there any other way ? I've checked on Mongo's doc and found a Phantom Custom Field Types but it looks like it's not saving in the db. In the rails console, I'll do the Model.status = "open" then saving it, it doesn't return any errors. So I close the console then open it again. Run the Model.status and it returns nil.
Thank you for reading and trying to help me !
First of all, there is good and bad in both MongoDB and PostgreSQL, it depends of the kind of features you need, see: https://www.geeksforgeeks.org/difference-between-postgresql-and-mongodb/
About the Phantom Custom Field Types, this is indeed doing the same stuff than ActiveRecord::Enum
but asking more code to write. Could you share the not working code that you've run for your test please ?
Edit 07/02/22:
Here is an example of you could use enum in mongo without writing too much code:
module MongoEnum
# Takes application-scope value and converts it to how it would be
# stored in the database. Converts invalid values to nil.
def mongoize(object)
mapping[object]
end
# Get the value as it was stored in the database, and convert to
# application-scope value. Converts invalid values to nil.
def demongoize(object)
inverse_mapping[object]
end
# Converts the object that was supplied to a criteria and converts it
# into a query-friendly form. Returns invalid values as is.
def evolve(object)
mapping.fetch(object, object)
end
def mapping
@mapping ||= self.const_get(:MAPPING).freeze
end
def inverse_mapping
@inverse_mapping ||= mapping.invert.freeze
end
end
class RoleEnum
extend MongoEnum
MAPPING = {
'admin' => 0,
'user' => 1,
}.freeze
end
class ColorEnum
extend MongoEnum
MAPPING = {
'black' => 0,
'white' => 1,
}.freeze
end
class Profile
include Mongoid::Document
field :color, type: ColorEnum
end
class User
include Mongoid::Document
field :role, type: RoleEnum
end
Disclaimer: I didn't test it in a real app, let me know if it does not work.