Rails - gema gmaps4rails en postgres

I successfully use the gmaps4rails gem on my local MySQL machine. However, when I deploy to PG on Heroku, I get the following error with respect to code that uses the gmaps4rails "near" function to find locations near the selected location:

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'

I suspect that this is because of something not being supported in this query in postgres, but the gem supposedly supports postgres. Any idea what's going on?

preguntado el 21 de mayo de 12 a las 19:05

1 Respuestas

Looks like PostgreSQL is complaining about this:

30.1926300 - venues.latitude

and the error message says that there is no operator that allows you to subtract a string from a number. I'd guess that you've created your venues.latitude columna como :string cuando debería ser un :float or :decimal. MySQL tries to be friendly be doing a lot of implicit type conversions behind your back, PostgreSQL tries to be friendly by making you say exactly what you mean to avoid confusion.

You're going to have to change your latitude column to a numeric type. Then you should start developing on top of PostgreSQL if you're going to deploy on top of Heroku's PostgreSQL, you should also match the PostgreSQL version in your development and deployment environments.

AFAIK, you'll have to change the type manually with an ALTERAR MESA como un simple change_column in a migration will probably fail with an error similar to

column "latitude" cannot be cast to type double precision

A migration like this:

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

should do the trick for PostgreSQL. Presumably you'll have to fix venues.longitude también.

contestado el 21 de mayo de 12 a las 20:05

"MySQL tries to be friendly be doing a lot of implicit type conversions behind your back, PostgreSQL tries to be friendly by making you say exactly what you mean to avoid confusion." - Wow! +++++++1 :) - Salil

@Salil: I don't like my databases making guesses about what I'm doing or what I mean: broken code is temporary, broken data is forever. - mu es demasiado corto

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.