英文:
Use Enumerators in Rails 7 with MongoDB
问题
I'm building a new project with Rails 7 and MongoDB 8. And I wanted to use enumerators for multiple fields ( states etc .. )
我正在使用Rails 7和MongoDB 8构建一个新项目。我想要为多个字段(状态等)使用枚举。
I wanted to use the gem mongoid-enum but it doesn't work with Mongo 8.
我想使用mongoid-enum宝石,但它不适用于Mongo 8。
Is switching to SQL database a solution? Or is there any other way?
切换到SQL数据库是一个解决方案吗?还是有其他方法?
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.
我查看了Mongo的文档,并找到了幻象自定义字段类型,但看起来它在数据库中没有保存。在rails控制台中,我执行Model.status = "open",然后保存它,没有返回任何错误。所以我关闭控制台,然后再次打开它。运行Model.status,它返回nil。
Thank you for reading and trying to help me!
谢谢你阅读并尝试帮助我!
1: https://www.mongodb.com/docs/mongoid/current/reference/fields/#phantom-custom-field-types
英文:
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 !
答案1
得分: 0
以下是您要的内容的中文翻译:
首先,无论是 MongoDB 还是 PostgreSQL,都有优点和缺点,这取决于您需要的功能类型,参见:https://www.geeksforgeeks.org/difference-between-postgresql-and-mongodb/
关于“Phantom Custom Field Types”,这确实与 ActiveRecord::Enum
做了相同的事情,但需要编写更多的代码。您能否分享一下您用于测试的不起作用的代码?
编辑于 2022年7月2日:
以下是一个示例,演示如何在 MongoDB 中使用枚举而无需编写太多代码:
module MongoEnum
# 获取应用程序范围的值并将其转换为数据库中的存储方式。将无效值转换为 nil。
def mongoize(object)
mapping[object]
end
# 获取数据库中存储的值,并将其转换为应用程序范围的值。将无效值转换为 nil。
def demongoize(object)
inverse_mapping[object]
end
# 将供应给条件的对象转换为查询友好的形式。将无效值返回为原值。
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
免责声明:我没有在实际应用程序中测试它,如果不起作用,请告诉我。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论