【问题标题】:cannot load 'rails.application.database_configuration' undefined method'[]' for nil:NilClass无法为 nil:NilClass 加载“rails.application.database_configuration”未定义方法“[]”
【发布时间】:2015-02-24 14:15:18
【问题描述】:

我将我的 database.yml 更改为在测试和开发中使用 sqlite3 数据库,在生产中使用 postgresql。我的应用程序在生产环境中运行良好,但是当我启动测试或开发环境时出现此错误:

Cannot load 'Rails.application.database_configuration':
undefined method'[]' for nil:NilClass (NoMethoError)

我的数据库.yml:

# SQLite version 3.x
#   gem install sqlite3
#
#   Ensure the SQLite 3 gem is defined in your Gemfile
#   gem 'sqlite3'
#
default: &default
  adapter: sqlite3
  pool: 5
  timeout: 5000

development:
  <<: *default
  database: db/development.sqlite3

# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
  <<: *default
  database: db/test.sqlite3

production:
  pool: 5
  timeout: 5000
  encoding: utf8
  adapter: postgresql
  host: <%= Rails.application.secrets[:database][:host]%>
  database: <%= Rails.application.secrets[:database][:name]%>
  username: <%= Rails.application.secrets[:database][:username]%>
  password: <%= Rails.application.secrets[:database][:password]%>

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4


    【解决方案1】:

    在新的 Rails 5.1.0 中遇到了这个问题,并在新的秘密加密文件中添加了我的变量。

    您的 nil 正在发生,因为即使它正在开发,它仍然会尝试加载所有内容,并且您正在从 nil -> something[:nil][:cant_grab_from_nil] 调用事物。快速解决方法是使用 if 语句。只有在新的 Rails 5.1 中使用秘密加密文件时才建议这样做。

    production:
      pool: 5
      timeout: 5000
      encoding: utf8
      adapter: postgresql
      <% if Rails.application.secrets[:database].present? %>
        host: <%= Rails.application.secrets[:database][:host]%>
        database: <%= Rails.application.secrets[:database][:name]%>
        username: <%= Rails.application.secrets[:database][:username]%>
        password: <%= Rails.application.secrets[:database][:password]%>
      <% end %>
    

    【讨论】:

    • 应该好好记录
    【解决方案2】:

    不谈安全性

    如果你要走这条路,这很好,你需要确保一件非常重要的事情:

    您的 secrets.yml 文件已安全配置,未检查到源代码控制中,任何不应该拥有的人都无法读取 访问

    在这种情况下,它的安全性不亚于为您的 Web 服务器设置一个锁定的 *key/*crt 证书文件,但您可能会存储多个机密。这样做正确比将秘密放入ENV 更可取,但仍有更好的选择。

    进一步阅读:

    您的实际问题

    您的问题是@tagCincy 的第二个想法(“b”),奇怪的是,这非常容易解决。就按照@Nik-Olai 的建议去做。在您的开发/测试环境中声明(尽管是空白)相同参数的值,如下所示:

    development:
      ...
      database:
        :name:
        :username:
        :password:
    
    test:
      # same thing here
    

    原因是,虽然 production 数据库配置不会在 developmenttest 环境中使用,但该配置的解析仍将发生。

    换一种方式,即使在测试/开发模式下,您的生产数据库设置仍会被解析(和 ERB 解释)。

    Rails.application.secrets 依赖于环境,因此在开发和测试模式下Rails.application.secrets[:database] 将不存在,这意味着随后的[] 调用将命中nil 目标,瞧!

    【讨论】:

    • 我认为缺少“解决方案”部分哈哈
    【解决方案3】:
    host: <%= Rails.application.secrets[:database][:host]%>
    database: <%= Rails.application.secrets[:database][:name]%>
    username: <%= Rails.application.secrets[:database][:username]%>
    password: <%= Rails.application.secrets[:database][:password]%>
    

    哦主啊,不要这样做。出于多种原因,请勿这样做。

    在生产服务器上使用ENV vars:

    host: <%= ENV['DB_HOST'] %>
    database: <%= ENV['DB_NAME'] %>
    username: <%= ENV['DB_USER'] %>
    password: <%= ENV['DB_PASSEWORD'] %>
    

    然后你想进入你的 prod 服务器并在你的 shell 配置文件(.bashrc、.zshrc、.profile)中设置这些变量,如下所示:

    export DB_HOST=your_host
    export DB_NAME=your_name
    export DB_USER=your_user
    export DB_PASSWORD=your_password
    

    您的问题是两种可能的情况之一:

    一个。在机密文件之前加载数据库配置的竞争条件。

    b.您将您的 secrets.yml 分段为环境,并且没有用于开发/测试环境的那些节点。

    【讨论】:

    • 感谢让我顺利,原因是 secrets.yml 中缺少节点
    • so.. 它归结为在secrets.yml 中为developmenttest 环境添加database 部分。对吗?
    • 我正在使用ENV 变量进行数据库连接,并且我已将我的设置放入secrets.yml.. 但是当运行rails s 并尝试访问rails 应用程序时,我收到此错误@ 987654333@.. 有什么想法吗?
    • 虽然您可能已经解决了眼前的问题,但将 ENV 用于机密是一个坏主意(尽管它非常受欢迎)。更多信息:movingfast.io/articles/environment-variables-considered-harmful
    • @Lykos 这意味着 mysql 的命令行调用看不到密码,在这种情况下,这可能意味着密码没有被引用和一些时髦的字符(例如,'#' , '&' 等)正在由你的 shell 解释。
    猜你喜欢
    • 2014-09-16
    • 2015-12-20
    • 2015-07-20
    • 2011-07-27
    • 2013-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多