Ruby on Rails + PostGIS model custom initialization and custom JSON output

xissburg Source

I am using PostgreSQL + PostGIS to work with spatial data and I am also using this gem activerecord-postgis-adapter to keep it easy to write code. I have this model

class Device < ActiveRecord::Base
  attr_accessible :location
  self.rgeo_factory_generator = RGeo::Geos.factory_generator
end

Where :location should be a PostGIS POINT. To create new instances of Device (in the controller's create method, for example) I can do this:

params = { location: "POINT (-26 -43)" }
@device = Device.new(params)

Where "POINT (-26 -43)" is a point with latitude -26 and longitude -43 in the WKT (Well Known Text) format. I would like to be able to hide this implementation detail and make it possible to write:

params = { latitude: -26, longitude: -43 }
@device = Device.new(params)

Perhaps I could achieve this by overriding the after_initialize method in my Device class. What else can I do?

There's one more thing.. I also need to output this object in JSON. Right now I get

{ "location": "POINT (-26 -43)" }

However, I'd like to have something like

{ "location": { "latitude": -26, "longitude": -43 } }

A quick n' dirty solution to this would be to override the as_json method. Any other suggestions?

Thanks.

ruby-on-railsactiverecordpostgis

Answers

answered 2 years ago G. I. Joe #1

All you need to do is overwrite in Device class the method as_json to replace the location key by the wanted one:

class Device < ActiveRecord::Base
  ...
  def as_json(options = {})
    json = super(options)
    json.merge(location_as_formatted_hash)
  end

  private

  def location_as_formatted_hash
    { location: { latitude: location.lat, longitude: location.lon } }
  end
end

And with this you are going to have the next:

Device.first.to_json
{ \"location\": { \"latitude\": -26, \"longitude\": -43 } }

Instead of this:

Device.first.to_json
{ \"location\": \"POINT (-26 -43)\" }

comments powered by Disqus