乐者为王

Do one thing, and do it well.

部署应用到Heroku时的问题

Heroku现在已经是纯粹的只读PaaS了,也就是说以前还支持的SQlite现在也不能使用了。因此部署到Heroku上的Rails应用需要把使用的数据库改成PostgreSQL,并且要关闭assets的预编译功能。

修改Gemfile,将SQLite换成PostgreSQL:

1
2
# gem 'sqlite3'
gem 'pg'

在config/application.rb中添加:

1
config.assets.initialize_on_precompile = false

股票功能需要导入交割单文件,因为导入后的文本文件不再使用,可以把上传路径由public/uploads改为tmp,这样就避免了Heroku不能写文件的问题。

应用上传后运行时出现异常,使用heroku logs -t查看日志发现有如下错误:

1
Error: column "stocks.share_name" must appear in the GROUP BY clause or be used in an aggregate function

这是因为在控制器中有这么一行代码:

1
current_user.stocks.select("share_code, share_name, sum(actual_amount) as amount").group("share_code")

在PostgreSQL中这会有问题。比如下面的数据表:

执行上面的SQL语句后,share_name的值到底是取Ruby呢还是ST Ruby?解决这个问题的方法是使用aggregate函数。

1
current_user.stocks.select("share_code, max(share_name) as share_name, sum(actual_amount) as amount").group("share_code")

使用PostgreSQL还有个问题,就是decimal类型的字段,取出来的值是字符串类型。例如:

1
if stock.amount < 0

它会报错误:

1
ArgumentError (comparison of String with 0 failed)

这个可以使用to_f函数解决:

1
if stock.amount.to_f < 0

Comments