Rails database.yml 读取环境变量出错

runup · 2016年10月31日 · 最后由 adamshen 回复于 2016年11月01日 · 3306 次阅读

问题描述: 在本机设置环境变量 PASSWORD=root,在 database.yml 中书写如下:

default: &default
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: root
  password: ['PASSWORD']
  socket: /tmp/mysql.sock

rails db:create 报错如下:

Mysql2::Error: Access denied for user 'root'@'localhost' (using password: NO)

我使用的版本是 rails5.0.0.1, 本机是 OS X,数据库是 mysql5.7。其中环境变量的设置方式:刚开始的时候是在.bash_profile 中设置 export PASSWORD=root,但是发现在终端中输入 env 没有出现 PASSWORD 的值,参考了装了 ohmyzsh,为啥.bash_profile 就不执行了...那改环境变量应该去哪呢?,因为安装了 zsh,并且是直接 zsh 启动,因此在按照该链接的方式,在.bash_profile 中设置 export PASSWORD=root,同时在.zshrc 中执行 source .bash_profile 语句,终端中输入 env,显示出来 PASSWORD=root,但是 database 文件没有读取出 ['PASSWORD'] 的值,为何?

另外: 1、排除的数据库出错的可能性,我的数据库密码是 root, 在 database.yml 文件中进行硬编码,password: root, rails db:create 是成功的。 2、['PASSWORD'] 的值在 rails 中也能够读取成功,可以通过在 controller 中将 ['PASSWORD'] 赋值给实例变量,并且将其呈现在 view 中。 3、尝试了 dotenv,出现上面同样的问题。

解决:

password: ['PASSWORD'] #错误写法
password: <%= ENV["PASSWORD"] %> #正确写法

不知为何自己一直执着于错误写法。

谁告诉你是怎么用的?

default: &default
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: root
  password: <%= ENV['PASSWORD'] %>
  socket: /tmp/mysql.sock

#3 楼 @huacnlee 也是不行。参考了How to send emails in Rails格式也是这样的写法。

楼主,用 3 楼的格式语法,运行PASSWORD=password rails c 然后再测试一下ENV['PASSWORD']

zsh 的坏境变量可以在~/.zsh.after/my_conf.zsh里设置export PASSWORD=password

#5 楼 @flemon1986

rails c  ENV['PASSWORD'] #root
PASSWORD=password rails c #password

在终端执行 env 显示出来如下结果应该是说明变量已经设置成功了吧。

PASSWORD=root

#7 楼 @runup 看似成功了。。。应该也是成功了

临时的上面那样用就可以,或者命令行 export 持久的就在 rc 文件里面 export

#8 楼 @flemon1986 我这里还是会报错

#11 楼 @jiazhen 尝试了 dotenv,通过在在 controller 中将 ['PASSWORD'] 赋值给实例变量,并且将其呈现在 view 中,这样子能成功,但是用到数据库上面最终还是报如上的错误。

  • DBPASS=pass rails c 当前命令有效;
  • export 一般在当前 terminal tab 有效;
export DBPASS=pass
rails c
unset DBPASS
  • export in .zshrc or .bashrc etc... 当前用户下有效;
~/.zshrc
export DBPASS=pass
  • export in /etc/profile 全局有效,也就是所有用户
panadishi[master] % cat /etc/profile
# System-wide .profile for sh(1)

export DBPASS=pass

用法就是三楼的 erb

#14 楼 @flowerwrong 谢谢解释的这么详细 我给的问题里面应该是对全局有效的,不过暂时没有找到解决这个问题的方法。

不明白你为什么用 ['PASSWORD']. ERB 明确是用 <%= ENV['PASSWORD']%>

['PASSWORD']

Started GET "/" for ::1 at 2016-10-31 15:35:34 +0000
Processing by StaticPagesController#home as HTML
{:adapter=>"postgresql", :encoding=>"utf8", :database=>"dev", :password=>["PASSWORD"], :pool=>5, :timeout=>5000}

ENV['PASSWORD']

Started GET "/" for ::1 at 2016-10-31 15:35:46 +0000
  ActiveRecord::SchemaMigration Load (0.4ms)  SELECT "schema_migrations".* FROM "schema_migrations"
Processing by StaticPagesController#home as HTML
{:adapter=>"postgresql", :encoding=>"utf8", :database=>"dev", :password=>111, :pool=>5, :timeout=>5000}

#15 楼 @runup 我没见过这样的password: ['PASSWORD'],我猜是 console 里面打印 password 的时候为了安全过滤成了['PASSWORD'];老老实实写 erb。 你可以通过 terminal 里面echo $PASSWORD验证环境变量是否设置正确。

@jiazhen 终于反应过来了 感谢。不能盯屏幕太久。

为了自己的好奇心,找了一下源码,Rails initalizer hook 明确用的是 ERB https://github.com/rails/rails/blob/master/railties/lib/rails/application/configuration.rb#L129-L152

#19 楼 @jiazhen 源码用 erb 解析 yml,刚才冒出来的问题是为什么可以在 yml 文件中使用 erb.

#17 楼 @flowerwrong 恩 确实是我的格式问题 谢谢指导。

huacnlee 关闭了讨论。 11月01日 09:34
需要 登录 后方可回复, 如果你还没有账号请 注册新账号