如何在Rails应用中查询无对应类的MongoDB数据?
绕过Rails模型依赖查询MongoDB集合
刚好遇到过类似的需求,其实不用纠结safe_constantize返回nil的问题,直接操作MongoDB的底层客户端就能解决,这样不管集合对应的模型在Rails里是否存在,都能拿到普通的键值对数组。
方法一:直接使用MongoDB原生客户端查询
如果你的Rails项目用的是Mongoid,框架已经帮你维护好了数据库连接,直接拿这个连接操作集合就行:
- 获取默认的MongoDB客户端实例
client = Mongoid::Clients.default - 直接通过集合名称(字符串转成符号)执行查询
这里的# 比如要查名为"unknown_classes"的集合 results = client[:unknown_classes].find({ foo: "bar" }).to_a.map(&:to_h)results就是纯Ruby哈希数组,不再是BSON::Document对象,完全满足你的需求。
方法二:封装通用查询方法(兼容已知/未知模型)
如果想写一个通用方法,既能处理存在Rails模型的集合,也能处理不存在的,可以这样封装:
def fetch_from_collection(collection_identifier, query = {}) client = Mongoid::Clients.default # 尝试把集合名转成模型类名并常量化 model = collection_identifier.classify.safe_constantize # 模型存在就用模型的collection,否则直接操作客户端的集合 target_collection = model ? model.collection : client[collection_identifier.to_sym] # 转成普通哈希数组返回 target_collection.find(query).map(&:to_h) end # 使用示例 # 查询有对应模型的集合 fetch_from_collection("my_classes", { foo: "bar" }) # 查询没有对应模型的集合 fetch_from_collection("unknown_classes", { foo: "bar" })
原理说明
Mongoid::Clients.default直接对接MongoDB的原生驱动,操作集合时不依赖Rails模型的定义。查询返回的BSON::Document本身可以通过to_h方法转成普通Ruby哈希,所以最后一步map(&:to_h)就能得到你想要的普通键值对数组。
内容的提问来源于stack exchange,提问作者JohnSmith1976
相关产品推荐
相关产品推荐

