rgeo/activerecord-postgis-adapter

Clarify point -> st_point while upgrading

Closed this issue · 9 comments

Hi folks, I am currently upgrading from Rails 4.2x to 5.1.x, and trying to better understand the points to update for this library.

I understand that the point type is now st_point (I'm not using polygon) but wasn't really sure where all that would imply a change.. so would like to confirm and clarify. (and hopefully it would also be helpful to someone else in the future).

  1. Update schema to reflect that change below:
create_table "locations", id: :serial, force: :cascade do |t|
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.geography "coordinates", limit: {:srid=>4326, :type=>"point", :geographic=>true} #this should be :type => "st_point"
  t.index ["coordinates"], name: "index_locations_on_coordinates", using: :gist
end
  1. Another question here is that the schema.rb shows t.geography rather than t.point - is that expected?

  2. Wherever point is being used as :geo_type, like below, replace with st_point?

locFactory = RGeo::ActiveRecord::SpatialFactoryStore.instance.factory(:geo_type => 'point')

But the confusion here is in the README, under the 'Configuring ActiveRecord' section, the documentation is still using point and not st_point. So, should this be updated in the README?

  1. Is my understanding correct that the line below needs no modification:
record.lonlat = 'POINT(-122 47)'  # sets the value to the given point

Thank you!

To add to that, another upgrade issue below related to (2) above:

  1. On db:load, migrations are erroring out here:
t.geography "coordinates", limit: {:srid=>4326, :type=>"st_point", :geographic=>true}

with this error message:

NoMethodError: undefined method `geography' for #<ActiveRecord::ConnectionAdapters::PostgreSQL::TableDefinition:0x007f8142d17ef8>

@teeparham Any thoughts on these questions if and when you have a moment?

FWIW, here are the versions of different packages:

activerecord-postgis-adapter (5.0.2)
  activerecord (~> 5.1)
  rgeo-activerecord (~> 5.1)

PostGIS is on 2.2.2, trying to upgrade to 2.3.3 to see if that solves the issue.

I agree this is a bit confusing. There are different type keys used in different places. The type key within the limit hash should be point. However, this has all been tested on AR 5.0 and 5.1 and works.

In response to your questions:

  1. Do not manually modify your schema.rb file. You can re-export it with rake db:schema:dump.
  2. Yes, do not manually modify your schema.rb file.
  3. No, geo_type values in SpatialFactoryStore do not need the st_ prefix. See https://github.com/rgeo/rgeo-activerecord#spatial-factories-for-columns
  4. Correct. The string value there is WKT.

@teeparham Thank you for the response! Could you respond to the 5 point above as well (the NoMethodError for geography)?

Here is it again to prevent scrolling:

On rake db:schema:load, migrations are erroring out here:

t.geography "coordinates", limit: {:srid=>4326, :type=>"st_point", :geographic=>true}

with this error message:

NoMethodError: undefined method `geography' for #<ActiveRecord::ConnectionAdapters::PostgreSQL::TableDefinition:0x007f8142d17ef8>
  1. Make sure you specify your adapter as postgis, and I think the type should be point in the limit hash. #174 might be helpful

@teeparham Appreciate you helping!

My adapter is set as postgis (database.yml below). Relevant section of my database.yml below:

default: &default
  adapter: postgresql
  encoding: unicode
  # For details on connection pooling, see Rails configuration guide
  # http://guides.rubyonrails.org/configuring.html#database-pooling
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

development:
  <<: *default
  database: s-api_development
  adapter: postgis
  schema_search_path: public, postgis

I think the type should be point in the limit hash

It was set as point but when I first do rails db:schema:dump, then it changes to st_point. Is that not supposed to be the case? (Also, either way, I see the NoMethodError on geography).

Also, I had looked at that issue and my understanding was that in that issue, folks were facing the issue when adding a new column to an existing model and fixed it by setting ENV['DATABASE_URL'] to postgis incase that was being used.

In my case, I'm on my local box and DATABASE_URL isn't being used anywhere. And I am getting the error just by upgrading the packages, and running the rails db:schema:load command.


FWIW, I also have the following initializer file:

RGeo::ActiveRecord::SpatialFactoryStore.instance.tap do |config|
	# By default, use the GEOS implementation for spatial columns.
	config.default = RGeo::Geos.factory_generator

	# But use a geographic implementation for point columns.
	config.register(RGeo::Geographic.spherical_factory(srid: 4326), geo_type: "point")
	#config.default = RGeo::Geographic.spherical_factory(srid: 4326)
end

What does the error indicate? That the configuration isn't set up at Rails level, or something at the DB level?

FWIW, I created a new test Rails 5 project, followed the instructions in the README to set it up and created a new rails resource (rails g resource Location lonlat:st_point name:string). It migrates properly but then if I try to rails db:schema:load on this newly created setup, I still get the same error:

# anuj at Anujs-MBP in ~/Github/rails-rgeo-upgrade-test/my_app on git:master ✖︎ [18:49:14]
→ rails db:schema:load
-- enable_extension("plpgsql")
   -> 0.0184s
-- enable_extension("postgis")
   -> 0.0031s
-- create_table("locations", {:force=>:cascade})
   -> 0.0864s
-- enable_extension("plpgsql")
   -> 0.0216s
-- enable_extension("postgis")
   -> 0.0035s
-- create_table("locations", {:force=>:cascade})
rails aborted!
NoMethodError: undefined method `geography' for #<ActiveRecord::ConnectionAdapters::PostgreSQL::TableDefinition:0x007fc83c360068>

Does this help narrow down what might be going on?

Change the adapter in your default section to postgis. It looks like db:schema:load is running twice (probably for development & test environments) & it worked the first time & not the second. I can't see your test section in your database.yml, but I bet the adapter is wrong.

Ah, that was it. I am still confused why since I was getting the error with rails db:schema:load RAILS_ENV=development as the command all this time as well. Do you know why that might be running for test environment even though the command sets RAILS_ENV to development?

But you were right that they were running twice, and it worked the first time and not the second.

Thank you so much, and let me know if you think this should be a section within the README anywhere (like FAQ, etc). I'd be happy to make a PR for that!