Escape '@' in names

61 views Asked by At

I use Rails 4.2.0 with ActiveResource to implement a webclient for server API. The problem I've faced is that server resources contains '@' and '@@' in attribute names. So these attributes can't be processed correctly by ActiveResource while creating ARes object. Example: server returns JSON data:

{"@@artist"=>
  {"@id"=>"some_text_id",
   "@name"=>"Carman",
   "@publisher"=>"Carmen radio",
   "@category"=>"Music",
   "@automaticallyGenerated"=>true,
   "@@options"=>{"@public"=>true, "@enabled"=>false},
   "_extended"=>{"@container"=>"Music box", "region"=>"Europe"}}}

The variant to rename attributes before ARes object is created: (remove '@' from name or replace it for another symbol). In that case I need to do back rename attributes before send POST, PUT requests (call resource.save for example) E.g. add '@' or '@@' in the beginning of the names.

Could you suggest more flexible and pretty variant?

1

There are 1 answers

2
Lukas Baliak On BEST ANSWER

I rly dont know what ist your output, but you can use something like this. This is just example.

input = {
  "@@artist"=>
  {"@id"=>"some_text_id",
  "@name"=>"Carman",
  "@publisher"=>"Carmen radio",
  "@category"=>"Music",
  "@automaticallyGenerated"=>true,
  "@@options"=>{"@public"=>true, "@enabled"=>false},
  "_extended"=>{"@container"=>"Music box", "region"=>"Europe"}
  }
}

def transcode(hash)
  result = {}
  hash.each do |k, v|
    result[k.gsub(/@*/, "")] = ( Hash === v ? transcode(v) : v )
  end
  result
end

output = transcode(input)

#{
#  "artist" => {
#  "id" => "some_text_id",
#  "name" => "Carman",
#  "publisher" => "Carmen radio",
#  "category" => "Music",
#  "automaticallyGenerated" => true,
#  "options" => {
#  "public" => true,
#  "enabled" => false
#  },
#  "_extended" => {
#  "container" => "Music box",
#  "region" => "Europe"
#  }
#  }
#}

BACK

input = {
  "@@artist"=>
  {"@id"=>"some_text_id",
  "@name"=>"Carman",
  "@publisher"=>"Carmen radio",
  "@category"=>"Music",
  "@automaticallyGenerated"=>true,
  "@@options"=>{"@public"=>true, "@enabled"=>false},
  "_extended"=>{"@container"=>"Music box", "region"=>"Europe"}
  }
}

def transcode(hash)
  result = {}
  hash.each do |k, v|
    result[k.gsub(/@*/, "")] = ( Hash === v ? transcode(v) : v )
  end
  result
end

def transcode_back(hash, output)
  result = {}
  hash.each do |k, v|
    value = output[k.gsub(/@*/, "")]
    result[k] = ( Hash === value ? transcode_back(v, value) : value )
  end
  result
end

output = transcode(input)

# you can modify values
#output["artist"]["name"] = "CarmanNew"

result = transcode_back(input, output)

output == result # is same ?
# true