【问题标题】:How can I dynamically call a Model using Mongoid when I only know the collection name?当我只知道集合名称时,如何使用 Mongoid 动态调用模型?
【发布时间】:2021-08-25 20:09:00
【问题描述】:

假设我有 20 多个模型,其中一个称为 Job

module API
  class Job
    include Mongoid::Document
    # ...

    store_in collection: :jobs

    # ...
  end
end

我正在处理一些 HTTP webhook,我正在指定系统管理员想要订阅更新的集合。

也就是说,我会知道集合叫jobs

known_info = { db_name: 'x', collection: 'jobs', id: '6095d84c5be78a26cc9d837b' }

## this is the normally way one would query jobs, but I want to mimic it
## dynamically not using the Module name
API::Job.find(known_info[:id])

## a second way that will NOT work,
## this evades all API code that I have written, I need to use my ruby code in the
## model with access to the class functions
document = nil
Mongoid.default_client.collections.each do |collection|
  next unless collection.namespace == "#{known_info[:db_name]}.#{known_info[:collection]}"

  document = collection.find(_id: known_info[:id]).limit(1).first
end

## this will return the record from the database,
## but it will not send it through the model, its just the raw database value
pp document =>
{"_id"=>BSON::ObjectId('6095d84c5be78a26cc9d837b'),
 ...
}

【问题讨论】:

  • ruby-on-rails 是否参与其中?如果ActiveSupport 可用,这会极大地改变答案。
  • 您不能调用模型,因为它不是方法。如果您还有其他问题,请进行相应编辑。
  • 你错了,我能弄明白。 @D.SM
  • @engineersmnky 没有轨道

标签: ruby mongodb mongoid


【解决方案1】:

我能够通过执行以下操作来弄清楚。

使用包装模型的命名空间,您可以查询常量并缩小范围

known_info = { db_name: 'x', collection: 'jobs', id: '6095d84c5be78a26cc9d837b' }
document = nil
API.constants.each do |constant|
  module_class = API.const_get(constant)
  ## skip of the constant is not a class
  next unless module_class.is_a?(Class)
  ## skip if the class does not have a method called "collection_name"
  next unless module_class.respond_to?(:collection_name)
  ## skip if the collection does not match the known collection
  next unless module_class.collection_name.to_s == known_info[:collection]

  document = module_class.find(known_info[:id])
end

p document

## success!

【讨论】:

    猜你喜欢
    • 2015-10-04
    • 1970-01-01
    • 2022-07-22
    • 2016-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多