繁体   English   中英

如何防止 Ruby 瞄准 gem 的 class 而不是我的 class?

[英]How can I prevent Ruby from targeting a gem's class instead of my class?

我在使用官方 SendGrid gem的 Rails 代码库中遇到问题。 发生相同行为的两个单独实例。

第一个例子

我有一个Engine class:

module API
  class Engine < ::Rails::Engine
    isolate_namespace API
  end
  ...
end

曾经在我的路线中指的是 class,如下所示:

mount API::Engine, at: :api, as: :api

...但我偶尔会收到此错误: uninitialized constant SendGrid::API:Engine (我的意思是“偶尔”字面意思;它似乎在开发过程中随机发生,刷新会修复它。)所以,我将这一行改为:

mount ::API::Engine, at: :api, as: :api

我认为应该明确地针对我的API而不是 SendGrid 的,但是在开发与 SendGrid 相关的代码时,我仍然偶尔会遇到错误。

第二个例子

这个似乎更陌生。 这个问题是本周才出现的,让我意识到上面的例子并不是一个孤立的事件。

我有一个Response class:

class Survey::Response < Sequel::Model Sequel[:survey][:responses]
  ...
end

而我们的监控刚刚发现了这个错误:

NoMethodError
undefined method `[]' for SendGrid::Response:Class

...在这一行:

results = results.pluck(:response_id).uniq.map { |r| Survey::Response[r] }

这个例子似乎更加极端,因为我们明确地针对Survey::Response而显然不是针对SendGrid::Response

问题

我很想知道是什么原因造成的,但主要是我想知道如何阻止它。 我怎样才能 100% 确定一条线针对我的class 而不是sendgrid-ruby gem 的 class?

我确实找到了这个问题,得出的结论与我在第一个问题中所做的相同,尽管这个问题的问题得到了解决,而我的问题却没有。

我的问题是一个模块被包含在全局命名空间中,因此它的常量污染了整个代码库。

例如:

require 'sendgrid-ruby'
include SendGrid

module MyModule
  ...
end

以这种方式包含SendGrid可能会导致我的问题中描述的问题。 以这种方式包含任何 gem 都有可能导致类似的问题。

解决方案是仅包含必须的模块,例如:

require 'sendgrid-ruby'

module MyModule
  include SendGrid
  ...
  # I can refer to Email here, and it will target SendGrid::Email
  ...
end

...甚至更好,根本不包含模块,而是显式引用模块的类:

require 'sendgrid-ruby'

module MyModule
  ...
  # Instead of referring to Email, I must explicitly refer to SendGrid::Email
  ...
end

这个问题帮助我认识到了这个问题。 但由于在我的搜索中没有为我提出这个问题,我将把这个问题留在这里并为任何未来的旅行者回答。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM