我使用的是Ruby on Rails 5.2.8和Ruby 2.7.8版本,发现代码中有一个错误.代码应该在运行时判断模型是否已定义.起初我try 使用defined?方法,但由于开发环境懒惰加载模块,我遇到了意想不到的(对我来说)行为:

defined?(ModelToCheck) #=> nil
ModelToCheck
defined?(ModelToCheck) #=> true

所以只有在使用模型之后,它似乎才被定义.判断是否已定义的最佳方法是什么?

附言

配置懒惰加载的选项是:

# config/environments/development.rb
ExampleApp::Application.configure do
  config.eager_load = false

  # rest of the config
  # ...
end

目前我也try 使用Object.const_defined?方法,但又是同样的故事.

我有两个 idea :

  • 运行时不要判断模型是否已定义
  • NameError没有定义时,使用a begin rescue块来处理NameError,但它很难看,如果可以的话我不想使用它

推荐答案

实现这一目标的一种方法是使用#missing_name#missing_name?并拯救投掷的NameError:

begin
  HelloWorld
rescue NameError => e
  e.missing_name
end
# => "HelloWorld"

更多详细信息,请参阅docs.

由于您发现这很难看,您也可以将其包装成类似这样的方法:

def check_defined(constant)
  begin
    Oject.const_get(constant)
  rescue NameError => e
    !e.missing_name?(constant)
  end
  
  true
end

除此之外,您还应该判断这是否可能是由于Rails的加载问题造成的.

Ruby-on-rails相关问答推荐

如何在_serialize之前执行代码?""或者如何在序列化属性之前对属性进行清理?

`heroku Open`和`heroku run rake db:Migrate`不工作(";没有这样的文件或目录";)

如何在Rails中创建没有字符串的查询

无法在 Rails 中使用 wkhtmltopdf 写入临时文件

用变量替换 find_or_create_by 中的键

序列化来自关联的不可变数据是个好主意吗?

Rails 7 共享刺激控制器功能

我如何在不同的视图中使用助手

使用 Ruby on Rails 从原始 IP 地址获取用户国家名称

Rails 模型:您将如何创建一组预定义的属性?

Ruby 元素是否存在于数组中

Ruby on Rails:调试 rake 任务

Rails,设计认证,CSRF 问题

我可以在 twitter-bootstrap popover 数据内容中使用 html 标签吗?

如何覆盖:在 has_many 中定义的顺序

是否可以设置 travis 来运行多种语言的测试?

如何从 rails 控制器操作发出 404 响应?

Postgresql JSON 数据列不同

何时(如果)合并 ActiveRecord 迁移?

t.belongs_to 在迁移