To display address profile fields as markers on a google map, the address field objects need to be passed as json objects to javascript.
When calling to_json
on an ApplicationRecord
object, the database attributes are automatically exposed.
Given a ProfileFields::Address
model with label
, value
, longitude
and latitude
attributes, address_field.as_json
results in a Hash
, e.g. representation,
address_field.as_json # =>
{label: "Work address", value: "Willy-Brandt-Straße 1\n10557 Berlin",
longitude: ..., latitude: ...}
which is converted to a json string by to_json
:
address_field.to_json # =>
"{\"label\":\"Work address\",\"value\":\"Willy-Brandt-Straße 1\\n
10557 Berlin\",\"longitude\":...,\"latitude\":...}"
This is useful because it allows to use label
and value
later in javascript, for example to show tool tips for the map markers.
Other virtual attributes can be exposed by overriding the as_json
method.
For example, to expose a title
attribute, include it in the merged as_json
hash:
# app/models/profile_fields/address.rb
class ProfileFields::Address < ProfileFields::Base
# ...
# For example: "John Doe, Work address"
def title
"#{self.parent.name}, #{self.label}"
end
def as_json
super.merge {
title: self.title
}
end
end
The above example uses super
to call the original as_json
method, which returns the original attribute hash of the object, and merges it with the required position hash.
To understand the difference between as_json
and to_json
, have a look at this blog post by jjulian.
To render markers, the google maps api, by default, requires a position
hash which has longitude and latitude stored as lng
and lat
respectively.
This position hash can be created in javascript, later, or here when defining the json representation of the address field:
To provide this position
as json attribute of the address field, just override the as_json
method on the model.
# app/models/profile_fields/address.rb
class ProfileFields::Address < ProfileFields::Base
# ...
def as_json
super.merge {
# ...
position: {
lng: self.longitude,
lat: self.latitude
}
}
end
end