Rails - postgres上的gmaps4rails gem

时间:2012-05-21 18:06:30

标签: mysql ruby-on-rails ruby-on-rails-3 postgresql gmaps4rails

我在本地MySQL机器上成功使用了gmaps4rails gem。但是,当我在Heroku上部署到PG时,对于使用gmaps4rails“near”函数查找所选位置附近位置的代码,我收到以下错误:

2012-05-21T17:58:40+00:00 app[web.1]: ActiveRecord::StatementInvalid (PG::Error: ERROR:  operator does not exist: numeric - character varying
2012-05-21T17:58:40+00:00 app[web.1]:                                                              ^
2012-05-21T17:58:40+00:00 app[web.1]: LINE 1: ...8.755864232 * 2 * ASIN(SQRT(POWER(SIN((30.1926300 - venues.l...
2012-05-21T17:58:40+00:00 app[web.1]: HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.
2012-05-21T17:58:40+00:00 app[web.1]: : SELECT  venues.*, 3958.755864232 * 2 * ASIN(SQRT(POWER(SIN((30.1926300 - venues.latitude) * PI() / 180 / 2), 2) + COS(30.1926300 * PI() / 180) * COS(venues.latitude * PI() / 180) * POWER(SIN((-85.8356740 - venues.longitude) * PI() / 180 / 2), 2) )) AS distance, CAST(DEGREES(ATAN2( RADIANS(longitude - -85.8356740), RADIANS(latitude - 30.1926300))) + 360 AS decimal) % 360 AS bearing FROM "venues"  WHERE (3958.755864232 * 2 * ASIN(SQRT(POWER(SIN((30.1926300 - venues.latitude) * PI() / 180 / 2), 2) + COS(30.1926300 * PI() / 180) * COS(venues.latitude * PI() / 180) * POWER(SIN((-85.8356740 - venues.longitude) * PI() / 180 / 2), 2) )) <= 5) ORDER BY distance LIMIT 5):
2012-05-21T17:58:40+00:00 app[web.1]:   app/controllers/venues_controller.rb:22:in `show'

我怀疑这是因为postgres中的这个查询不支持某些东西,但是gem应该支持postgres。知道发生了什么事吗?

1 个答案:

答案 0 :(得分:4)

看起来PostgreSQL抱怨这个:

30.1926300 - venues.latitude

并且错误消息表明没有允许您从数字中减去字符串的运算符。我猜你已将venues.latitude列创建为:string,而它应该是:float or :decimal。 MySQL试图友好地在你的背后做很多隐式类型的转换,PostgreSQL试图通过让你说出你的意思来避免混淆来友好。

您必须将latitude列更改为数字类型。那么你应该在PostgreSQL之上开始开发,如果你要在Heroku的PostgreSQL之上部署,你也应该在开发和部署环境中匹配PostgreSQL版本。

AFAIK,您必须使用ALTER TABLE手动更改类型,因为迁移中的简单change_column可能会因类似

的错误而失败
  

列“latitude”无法强制转换为双精度类型

像这样的迁移:

def up
    connection.execute(%q{
        alter table venues
        alter column latitude
        type float using latitude::float
    })
end

应该为PostgreSQL做的伎俩。大概你也必须修复venues.longitude