Переименовать свойства ActiveResource

Я использую данные JSON из стороннего API, немного обрабатываю эти данные, а затем отправляю модели клиенту в виде JSON. Ключи для входящих данных названы не очень удачно. Некоторые из них являются аббревиатурами, некоторые просто кажутся случайными символами. Например:

{
  aikd: "some value"
  lrdf: 1 // I guess this is the ID
}

Я создаю модель Rails ActiveResource для обертывания этого ресурса, но не хотел бы получать доступ к этим свойствам через model.lrdf, так как не очевидно, что такое lrdf на самом деле! Вместо этого я хотел бы каким-то образом связать эти свойства с другим свойством, которое названо лучше. Что-то, чтобы я мог сказать model.id = 1 и автоматически установить lrdf в 1 или поместить model.id и автоматически вернуть 1. Кроме того, когда я вызываю model.to_json для отправки модели клиенту, я не хочу мой javascript, чтобы понять эти странные соглашения об именах.

Я пытался

alias id lrdf

но это дало мне ошибку, говоря, что метод lrdf не существует.

Другой вариант - просто обернуть свойства:

def id
  lrdf
end

Это работает, но когда я вызываю model.to_json, я снова вижу lrdf в качестве ключей.

Делал ли кто-нибудь что-нибудь подобное раньше? Что вы порекомендуете?


person Brad    schedule 13.04.2011    source источник


Ответы (2)


Вы пробовали использовать магию before_save? Возможно, вы могли бы определить attr_accessible :ldrf, а затем в своем фильтре before_save назначить ldrf вашему полю id. Не пробовал, но думаю должно работать.

attr_accessible :ldrf

before_save :map_attributes

protected
  def map_attributes
    {:ldrf=>:id}.each do |key, value|
      self.send("#{value}=", self.send(key))
    end
  end

Дай мне знать!

person christianblais    schedule 13.04.2011
comment
Я думаю, что это сработает для сохранений, но в моем случае данные доступны только для чтения, поэтому меня интересует только их преобразование при чтении. - person Brad; 14.04.2011
comment
В итоге я сделал что-то подобное, перезаписав метод загрузки ActiveResource::Base. - person Brad; 23.05.2011

Вы можете попробовать создать модуль форматирования на основе ActiveResource::Formats::JsonFormat и переопределить decode(). Если вам нужно обновить данные, вам также придется переопределить encode(). Посмотрите на свои локальные gems/activeresource-N.N.N/lib/active_resource/formats/json_format.rb, чтобы увидеть, что делает исходный форматировщик json.

Если имя вашей модели — Model, а средство форматирования — CleanupFormatter, просто выполните Model.format = CleanupFormatter.

module CleanupFormatter
  include ::ActiveResource::Formats::JsonFormat
  extend self
  # Set a constant for the mapping.
  # I'm pretty sure these should be strings. If not, try symbols.
  MAP = [['lrdf', 'id']]

  def decode(json)
    orig_hash = super
    new_hash = {}
    MAP.each {|old_name, new_name| new_hash[new_name] = orig_hash.delete(old_name) }
    # Comment the next line if you don't want to carry over fields missing from MAP
    new_hash.merge!(orig_hash)
    new_hash
  end
end

Это не связано с псевдонимами, как вы просили, но я думаю, что это помогает изолировать тарабарщину имен от вашей модели, которая никогда не узнает, что эти исходные имена существовали. И «to_json» будет отображать читаемые имена.

person Kelvin    schedule 14.04.2011