將模型屬性公開為 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