Is there a recommended way how to produce camelized keys by default during serialization by using AMS?
In small APIs one can just override the attributes hash, but is not a feasible way for bigger APIs.
I guess that probably the best way would be to fork AMS and camelize the keys somewhere in the overriden serialize method? Or do someone has better idea?
Btw some interesting links about snake_case vs. CamelCase in JSON:
I've been wondering about the same thing, this is what I've come up with so far:
I've extended the Hash class to allow easy camelization/underscoring of keys:
class Hash
def camelize_keys!
update_keys!(:camelize, :lower)
end
def underscore_keys!
update_keys!(:underscore)
end
def update_keys!(method, *args)
self.keys.each do |key|
updated_key = key.to_s.send(method, *args).to_sym
self[updated_key] = self.delete(key)
self[updated_key].update_keys!(method, *args) if self[updated_key].kind_of? Hash
end
self
end
end
I've created a BaseSerializer class that all my serializers inherit from in which I override #attributes:
class BaseSerializer < ActiveModel::Serializer
def attributes
super.camelize_keys!
end
end
And in my ApplicationController I'll set a before filter to update the params to underscores.
Curious to get some feedback on that
Nice one, this seems reasonable, thank you @jurre for sharing!
Just figured out that in order to also correctly camelize any has_many attributes I had to overwrite has_many as well, the same would go for has_one, both call associate so it might be interesting to look into overwriting that.
class BaseSerializer < ActiveModel::Serializer
def attributes
super.camelize_keys!
end
def self.has_many(*args)
options = args.extract_options!
options.reverse_merge!({ key: args.first.to_s.camelize(:lower).to_sym })
args << options
super(*args)
end
end
What about doing something like ...
class ApplicationSerializer < ActiveModel::Serializer
def serializable_hash(options={})
Hash[super.to_a.map { |k, v| [k.to_s.camelize, v] }]
end
end
Check it out if something like works for you and let me know.
Also test that using master please.
Thanks.
I will provide some conveniences for converting keys in 0.9
Thanks @spastorino, I'll give that a try, we would probably need to call to_s on the key first for it to work though (there's no camelize on Symbol I think)
Yep, fixed!
I created a pull request for this in #428 would love some feedback on it.
:+1:
If you prefer lowerCamelCase and symbol keys, you may want something like this (doesn't support has_many):
class ApplicationSerializer < ActiveModel::Serializer
private
def attributes
super.map { |k, v| [ k.to_s.camelize(:lower).to_sym, v ] }.to_h
end
end
This will be handled by individual adapters in 0.10, as per their formats.
Has anyone written a camelcase adapter for 0.10?
@ratbeard no, we haven't build a specific CamelCase adapter yet.
Some models have trailing questionmarks in method names like model.was_good? and I wanted it to translate to wasGood in JSON. Here's my solution. Some repetition for has_many/has_one/belongs_to - how would you simplify it?
class ApplicationSerializer < ActiveModel::Serializer
def attributes(options={})
super(options).map { |k, v| [ k.to_s.camelize(:lower).chomp('?').to_sym, v ] }.to_h
end
def self.has_many(*args)
options = args.extract_options!
options.reverse_merge!({ key: args.first.to_s.camelize(:lower).to_sym })
args << options
super(*args)
end
def self.has_one(*args)
options = args.extract_options!
options.reverse_merge!({ key: args.first.to_s.camelize(:lower).to_sym })
args << options
super(*args)
end
def self.belongs_to(*args)
options = args.extract_options!
options.reverse_merge!({ key: args.first.to_s.camelize(:lower).to_sym })
args << options
super(*args)
end
end
Here's the current code for associations in AMS: https://github.com/rails-api/active_model_serializers/blob/aaa60bfdc131cbd96b322037f56bce99a9f36de5/lib/active_model/serializer/associations.rb
hey ya'll
Just wanted to point out: https://github.com/domchristie/humps as a nice way to not have to change the API format (I'm partial to snake_case for API data) to fit the frontend library (React in my case).
It looks like using a key_transform might be a good solution for this
there is now also https://github.com/NullVoxPopuli/case_transform
which will eventually be pulled in to AMS when I get it having native extensions
@NullVoxPopuli, looking forward to it.
@thePooh case_transform is in AMS now, so you can optionally use the native extensions variant
Other option is to add:
ActiveModel::Serializer.config.key_transform = :camel_lower
ActiveModel::Serializer.config.default_includes = "**"
To the: active_model_serializers.rb
Everything that goes through the serializer will be camelCase
Other option is to add:
ActiveModel::Serializer.config.key_transform = :camel_lower ActiveModel::Serializer.config.default_includes = "**"To the: active_model_serializers.rb
Everything that goes through the serializer will be camelCase
This works fine for me. I could use it for different scopes in my app:
class BaseSerializer < ActiveModel::Serializer
ActiveModel::Serializer.config.key_transform = :underscore
end
Most helpful comment
Other option is to add:
ActiveModel::Serializer.config.key_transform = :camel_lower ActiveModel::Serializer.config.default_includes = "**"To the: active_model_serializers.rb
Everything that goes through the serializer will be camelCase