将模型属性公开为 json

要在 Google 地图上将地址配置文件字段显示为标记,需要将地址字段对象作为 json 对象传递给 javascript。

常规数据库属性

ApplicationRecord 对象上调用 to_json 时,会自动公开数据库属性。

给定 ProfileFields::Address 模型与 labelvaluelongitudelatitude 属性,address_field.as_json 导致 Hash,例如表示,

address_field.as_json  # =>
  {label: "Work address", value: "Willy-Brandt-Straße 1\n10557 Berlin",
    longitude: ..., latitude: ...}

to_json 转换为 json 字符串:

address_field.to_json  # =>
  "{\"label\":\"Work address\",\"value\":\"Willy-Brandt-Straße 1\\n
    10557 Berlin\",\"longitude\":...,\"latitude\":...}"

这很有用,因为它允许稍后在 javascript 中使用 labelvalue,例如显示地图标记的工具提示。

其他属性

通过覆盖 as_json 方法可以暴露其他虚拟属性。

例如,要公开 title 属性,请将其包含在合并的 as_json 哈希中:

# 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

上面的例子使用 super 来调用原始的 as_json 方法,该方法返回对象的原始属性哈希值,并将其与所需的位置哈希值合并。

要了解 as_jsonto_json 之间的区别,请查看 jjulian 撰写的这篇博客文章

位置

为了渲染标记,默认情况下,谷歌地图 api 需要一个 position 哈希,其经度和纬度分别存储为 lnglat

此位置哈希可以在 javascript 中创建,稍后或在此处定义地址字段的 json 表示时:

要将此 position 作为地址字段的 json 属性提供,只需覆盖模型上的 as_json 方法即可。

# 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