Search code examples
ruby-on-railsherokupostgisrgeo

Heroku: error for PostGIS column in web dyno but not in one-off or worker dynos


I've got the beginnings of a spatial app (PostGIS + Rails + RGeo) with a single line_string column on one of my models. On my local machine everything is good, the problem is on Heroku web dynos, where Rails/activerecord doesn't recognise the RGeo/PostGIS line_string type.

Each time after deploying, the first time the model is loaded I see the following in the logs:

app[web.1]: unknown OID 17059: failed to recognize type of 'line_string'. It will be treated as String.

Then if I add some logging to STDOUT I can see:

mymodel.line_string.class # String
RGeo::Feature::Geometry.check_type(mymodel.line_string) # false

However, if I run a one-off dyno with rails console (heroku run rails c production) everything is good. I see the output I expect:

irb(main):001:0> mymodel.line_string.class
=> RGeo::Geographic::SphericalLineStringImpl

irb(main):002:0> RGeo::Feature::Geometry.check_type(mymodel.line_string)
=> true

It's also ok under worker dynos.

What would cause the unknown OID error? Why would one-off and worker dynos be able to work with this column perfectly but the web dyno not?


Solution

  • Puma was starting without configuration for PostGIS that I had added in application.rb. ActiveRecord started working with PostGIS once I added the following to config/puma.rb:

    on_worker_boot do
      if defined?(ActiveRecord::Base)
        config = ActiveRecord::Base.configurations[Rails.env] ||
          Rails.application.config.database_configuration[Rails.env]
        config['adapter'] = 'postgis'
        ActiveRecord::Base.establish_connection(config)
      end
    end
    
    on_restart do
      if defined?(ActiveRecord::Base)
        config = ActiveRecord::Base.configurations[Rails.env] ||
          Rails.application.config.database_configuration[Rails.env]
        config['adapter'] = 'postgis'
        ActiveRecord::Base.establish_connection(config)
      end
    end
    

    The other dyno types were just using application.rb so they were always configured correctly.