部署Ruby on Rails到Heroku时遇NoMethodError错误求助
我是一名JavaScript开发者,正在学习Ruby on Rails。部署项目到Heroku时遇到NoMethodError: undefined method []' for nil:NilClass错误,怀疑是master.key的问题,试过重新创建项目、更换新的master.key并重构所有代码,但错误依旧存在。
错误栈信息
rails aborted! NoMethodError: undefined method `[]' for nil:NilClass /app/config/environments/production.rb:124:in `block in <main>' ... `perform' /app/vendor/bundle/ruby/3.0.0/gems/railties-6.1.5/lib/rails/command.rb:50:in `invoke' /app/vendor/bundle/ruby/3.0.0/gems/railties-6.1.5/lib/rails/commands.rb:18:in `<main>' /app/vendor/bundle/ruby/3.0.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require' /app/vendor/bundle/ruby/3.0.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require' Tasks: TOP => db:migrate => db:load_config => environment (See full trace by running task with --trace)
production.rb代码片段
require 'active_support/core_ext/integer/time' # rubocop: disable Metrics/BlockLength Rails.application.configure do config.cache_classes = true config.eager_load = true # Full error reports are disabled and caching is turned on. config.consider_all_requests_local = false config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? config.active_storage.service = :local config.log_level = :info # Prepend all log lines with the following tags. config.log_tags = [:request_id] config.action_mailer.perform_caching = false config.i18n.fallbacks = true # Send deprecation notices to registered listeners. config.active_support.deprecation = :notify # Log disallowed deprecations. config.active_support.disallowed_deprecation = :log # Tell Active Support which deprecation messages to disallow. config.active_support.disallowed_deprecation_warnings = [] config.log_formatter = ::Logger::Formatter.new if ENV['RAILS_LOG_TO_STDOUT'].present? logger = ActiveSupport::Logger.new(STDOUT) logger.formatter = config.log_formatter config.logger = ActiveSupport::TaggedLogging.new(logger) end config.active_record.dump_schema_after_migration = false # Email config.action_mailer.default_url_options = { host: 'https://max-api-on-rails.herokuapp.com/' } config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { address: "smtp.gmail.com", port: 587, domain:'gmail.com', user_name: Rails.application.credentials.zoho[:user_name], password: Rails.application.credentials.zoho[:password], authentication: 'login', ssl: true, tls: true, enable_starttls_auto: true } end
问题定位
从错误栈和代码对应来看,报错行是production.rb的第124行,对应Rails.application.credentials.zoho[:user_name]或Rails.application.credentials.zoho[:password]——这说明Rails.application.credentials.zoho是nil,也就是Heroku环境中没有正确加载到zoho相关的凭据。
解决步骤
确认本地凭据配置
本地执行rails credentials:edit,检查config/credentials.yml.enc中是否存在格式正确的zoho节点:zoho: user_name: your_actual_username password: your_actual_password确保保存后,本地
master.key能正常解密该文件。配置Heroku环境的凭据
有两种方式可选:- 设置
RAILS_MASTER_KEY环境变量
复制本地config/master.key的内容,在终端执行:heroku config:set RAILS_MASTER_KEY=你的master.key字符串 - 单独设置Zoho凭据的环境变量
如果不想依赖master.key,直接在Heroku配置单独的变量:
同时修改heroku config:set ZOHO_USER_NAME=你的Zoho用户名 heroku config:set ZOHO_PASSWORD=你的Zoho密码production.rb中的SMTP配置:user_name: ENV['ZOHO_USER_NAME'], password: ENV['ZOHO_PASSWORD']
- 设置
验证Heroku环境的凭据加载情况
登录Heroku控制台执行:heroku run rails c在Rails控制台中测试:
# 如果用master.key方式 Rails.application.credentials.zoho # 查看是否返回nil # 如果用环境变量方式 ENV['ZOHO_USER_NAME'] # 查看是否有值检查部署日志
部署时查看Heroku的构建日志,确认是否有凭据加载失败的提示,比如master.key未找到、解密错误等信息。
额外提示
你代码中SMTP服务器用的是smtp.gmail.com,但凭据是Zoho的,这里存在不匹配的问题,后续会导致邮件发送失败。Zoho的SMTP服务器应为smtp.zoho.com,建议同步修正。
内容的提问来源于stack exchange,提问作者Macson Soares Rocha

