无法为nil:NilClass加载'rails.application.database_configuration'未定义的方法'[]'

时间:2015-02-24 14:15:18

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

我改变了我的database.yml,在测试和开发中使用sqlite3数据库,在生产中使用postgresql。我的应用程序在生产中运行良好,但是当我启动测试或开发环境时,我有这个错误:

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

我的database.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]%>

3 个答案:

答案 0 :(得分:4)

使用新的Rails 5.1.0进行此操作,并将我的变量添加到新的机密加密文件中。

你的nil正在发生,因为即使它是开发,它仍然会尝试加载所有内容而你从nil调用的东西 - &gt;东西[:无] [: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 %>

答案 1 :(得分:1)

除了安全性

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

  

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

在这种情况下,除了您可能存储多个机密信息之外,它的安全性与为您的Web服务器设置锁定的*key/*crt证书文件同样安全。正确地执行此 比在ENV中放置秘密更可取,但仍有更好的选择。

进一步阅读:

您的实际问题

你的问题是@ tagCincy的第二个想法(“b”),奇怪的是,这很容易解决。就像@ Nik-Olai建议的那样做。在dev / test环境中声明(尽管是空白的)相同参数的值,如下所示:

development:
  ...
  database:
    :name:
    :username:
    :password:

test:
  # same thing here

原因是,production数据库配置未在developmenttest环境中使用, 解析 该配置仍将发生。

换句话说,即使在测试/开发模式下,您的生产数据库设置仍将被解析(并且ERB解释)。

Rails.application.secrets与环境有关,因此在开发和测试模式下Rails.application.secrets[:database]将不存在,这意味着后续[]调用将达到零目标,瞧! / p>

答案 2 :(得分:-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变量:

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

您的问题是2个可能的事情之一:

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

湾您有secretts.yml分段为环境,并没有这些节点用于开发/测试环境。