我改变了我的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]%>
答案 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
数据库配置未在development
或test
环境中使用, 解析 该配置仍将发生。
换句话说,即使在测试/开发模式下,您的生产数据库设置仍将被解析(并且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分段为环境,并没有这些节点用于开发/测试环境。