ActiveRecord::ConnectionAdapters::Quoting

In commit 4893170da20eee28c016408a0f72f1996343a048, there has been a new method type_cast in quoting which is used to prepare sql- statements, before that, columns where asked to *quote* their own value as in using the database adapter to typecast before executing prepared stat… · rails/rails@a0d4c8d · GitHub,

This has broken almost all GIS gems that define their own *columns*, where should I ask if this was intended? since this can easily be fixed and made backward compatible by overriding the *else* in type_cast.

Yes, this change was intentional for supporting prepared statements. We could make it backwards compatible. But this is a completely new feature, so I'm not sure what that means.

Could you tell us what you're trying to do, and maybe there is a better, more future proof way to do it?

Of course, Here's my situation,

I am using spatial-adapter for a rails 3.1 app [ spatial-adapter worked just fine for a rails 3.0 app ], I followed the usual steps and created a geometry column with migrations and afterwards when I tried to create a new record in the database I got the following error:

ERROR: parse error - invalid geometry HINT: You must specify a valid OGC WKT geometry type such as POINT, LINESTRING or POLYGON

I googled a bit and this link came up ( which is one month old and didn't answer my question )

So I jumped into the rails code [ for the first time ], and found/ think that type_cast is the problem. I've patched the spatial-adapter code for project [ Actually I've change Quoting::type_cast through monkey patching, but It's easy to do it the other way. ]

Btw, I didn't know about the prepared statement, It's a grandiose feature to have. :slight_smile:

Of course, Here's my situation,

I am using spatial-adapter for a rails 3.1 app [ spatial-adapter worked just fine for a rails 3.0 app ], I followed the usual steps and created a geometry column with migrations and afterwards when I tried to create a new record in the database I got the following error:

ERROR: parse error - invalid geometry HINT: You must specify a valid OGC WKT geometry type such as POINT, LINESTRING or POLYGON

I googled a bit and this link came up ( which is one month old and didn't answer my question ) ruby - Rails - PostGIS + postgis_adapter Geometry Problem - Stack Overflow

So I jumped into the rails code [ for the first time ], and found/ think that type_cast is the problem. I've patched the spatial-adapter code for project [ Actually I've change Quoting::type_cast through monkey patching, but It's easy to do it the other way. ]

The type_cast method on the column is the wrong method to use in this case. Let's explore why that is the case.

If we look at the `type_cast` method on the column object in Rails, we'll see that it converts a type that comes *from* the database in to a type that we want to use in ruby land:

  https://github.com/rails/rails/blob/3-1-stable/activerecord/lib/active_record/connection_adapters/column.rb#L70-88

However, in this case, we're trying to convert Ruby object types in to a data type that the prepared statement can understand. Namely, strings, integers and possibly booleans. We have a default set of conversion types that work across all databases in the abstract adapter:

  https://github.com/rails/rails/blob/3-1-stable/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb#L45-76

And we have a specialization in the postgresql subclass:

  https://github.com/rails/rails/blob/3-1-stable/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L386-396

Recall that we are attempting to convert to a type that can be inserted in to the database. Then take a look at the `type_cast` implementation in the postgis adapter:

  https://github.com/nofxx/postgis_adapter/blob/master/lib/postgis_adapter/common_spatial_adapter.rb#L132-138

It is converting to a GeoRuby (which seems to be no longer maintained according to this site: http://georuby.rubyforge.org/) Geometry class. Postgres doesn't know what that type is, so it would be impossible to insert it to your database.

The best method for dealing with this is if the gem provided a subclass of the postgresql adapter that adds PostGIS functionality. Which is exactly what this one does:

  https://github.com/dazuma/activerecord-postgis-adapter

Hope that helps!

Btw, I didn't know about the prepared statement, It's a grandiose feature to have. :slight_smile:

Yes. I'm happy to be using them!

Thank you so much for the detailed explanation,

That's how I made my monkey-patch, created a new type in Quoting module.

Unfortunately the activerecord-postgist-adapter has some issues with rails 3.1 ( It's even in the issues ) that's why I used my good old spatial-adapter.

It certainly helped a lot. :slight_smile: Thanks again.