0
class ChatMessage < ActiveResource::Base
 alias_attribute :user_id, :userId
 alias_attribute :chat_id, :chatId
 alias_attribute :message_text, :MessageText
 ...

I Have the problem that what I return from an API has attribute names that I don't like, e.g. see camelCaps. I don't want to do this to every model in my application. Is there some method missing magic I could apply?

Cheers Thomas

plotti
  • 137
  • 1
  • 9
  • You are getting a hash with java style keys to initialize your models, right? – ichigolas Oct 21 '13 at 14:39
  • yes e.g. {"id"=>10569, "vote"=>0, "instanceType"=>"show", "instanceId"=>"2099", "userId"=>9, "createdOn"=>"2013-08-21 13:54:54"} – plotti Oct 21 '13 at 15:30
  • possible duplicate of [Convert CamelCase xml/json to ruby named attributes with ActiveResource](http://stackoverflow.com/questions/2209173/convert-camelcase-xml-json-to-ruby-named-attributes-with-activeresource) – phoet Oct 21 '13 at 15:52

1 Answers1

2

You can do a little of metaprogramming here:

module JavaAliasing
  def initialize(hash)
    super(Hash[hash.map do |k,v|
      [k.to_s.gsub(/[a-z][A-Z]/) { |s| s.split('').join('_') }.downcase.to_sym, v]
    end])
  end
end

Let me illustrate this:

class Instantiator
  def initialize(hash)
    hash.each { |k,v| instance_variable_set "@#{k}", v }
  end
end

Instantiator.new(asdf: 2).instance_variable_get('@asdf') #=> 2

class MyARModel < Instantiator
  include JavaAliasing
end

MyARModel.new(asdfQWER: 2).instance_variable_get("@asdf_qwer") #=> 2

Here, a real life example (rails 4.0):

> Player.send :include, JavaAliasing
> Player.new(name: 'pololo', username: 'asdf', 'teamId' => 23)
=> #<Player id: nil, name: "pololo", username: "asdf", email: nil, type: "Player", created_at: nil, updated_at: nil, provider: nil, uid: nil, team_id: 23, last_login: nil, last_activity: nil>
ichigolas
  • 7,595
  • 27
  • 50
  • it looks nice although it creates instance variables, is there no other way around it? – plotti Oct 21 '13 at 18:38
  • The initializer at `JavaAliasing` just transforms the hash and `super`s it. So you should integrate it into your AR models without interfering with the normal functioning of AR. The parent class is the one doing stuff with that hash, in this case `Instantiator`, in the real case, `ActiveRecord::Base` – ichigolas Oct 21 '13 at 19:41