Ruby on Rails初始化Cloudinary运行rake -t出现undefined method `[]' for nil报错
NoMethodError: undefined method '[]' for nil:NilClass报错本质是你取值链的某一步返回了nil,即Rails.application.credentials[Rails.env.to_sym]或者该值下的:cloudinary属性为空,才会触发nil对象调用[]方法的异常。
- 第一步:校验credentials嵌套结构
执行rails credentials:edit打开凭据配置文件,确认配置结构是按环境嵌套的,示例正确结构如下:
development: cloudinary: cloud_name: 你的cloud_name api_key: 你的api_key api_secret: 你的api_secret test: cloudinary: cloud_name: 你的cloud_name api_key: 你的api_key api_secret: 你的api_secret production: cloudinary: cloud_name: 你的cloud_name api_key: 你的api_key api_secret: 你的api_secret
不要将cloudinary配置直接写在最外层,否则按环境取值时会拿到nil。
第二步:校验运行环境匹配
默认执行rake -t使用的是development环境,如果你只配置了production环境的Cloudinary参数,就会出现报错。可以指定环境运行命令验证:RAILS_ENV=production rake -t,如果运行正常说明是环境不匹配问题。第三步:使用安全取值方法优化代码
用Rails内置的dig方法替代链式[]取值,避免某层为空时直接抛异常,同时方便定位问题,修改后的配置代码如下:
Cloudinary.config do |config| config.cloud_name = Rails.application.credentials.dig(Rails.env.to_sym, :cloudinary, :cloud_name) config.api_key = Rails.application.credentials.dig(Rails.env.to_sym, :cloudinary, :api_key) config.api_secret = Rails.application.credentials.dig(Rails.env.to_sym, :cloudinary, :api_secret) end
如需排查取值问题,可以在配置块前加调试代码puts Rails.application.credentials.inspect,运行rake命令时查看输出的凭据结构即可确认哪层配置缺失。
第四步:校验解密密钥是否正确
如果你是协同开发场景,确认本地config/master.key(Rails 7+对应环境密钥为config/credentials/[环境名].key)和配置Cloudinary参数时使用的密钥一致,密钥错误会导致credentials解密后全为空值。备选方案:使用环境变量配置
如果不想通过credentials管理参数,可以直接读取环境变量配置Cloudinary,代码更简单不易出错:
Cloudinary.config do |config| config.cloud_name = ENV['CLOUDINARY_CLOUD_NAME'] config.api_key = ENV['CLOUDINARY_API_KEY'] config.api_secret = ENV['CLOUDINARY_API_SECRET'] end
提前在对应运行环境配置好三个环境变量即可生效。
内容的提问来源于stack exchange,提问作者k10a

