I have a serializer for my rest API. Currently, it looks like:
class TestSerializer < ActiveModel::Serializer
attributes :id, :name, :field_one__c, :field_two__c
end
I'm wondering if there are any ways to filter all the fields to have the __c
removed when serializing, if there is a way to apply logic to ALL fields.
The case is I have a lot of fields with __c
on the end, and I'd like to remove them all with a minimal amount of code on the serializer level.
Yes you can customize an attribute name in the serializer using the :key
option:
attribute :field_one__c, key: :field_one
attribute :field_two__c, key: :field_two
You can also make any attribute conditional using :if
or :unless
options.
For your special case, you can hack this by defining the attributes
class method before the attributes list:
class TestSerializer < ActiveModel::Serializer
class << self
def attributes(*attrs)
attrs.each do |attr|
options = {}
options[:key] = attr.to_s[0..-4].to_sym if attr.to_s.end_with?('__c')
attribute(attr, options)
end
end
end
attributes :id, :name, :field_one__c, :field_two__c
end
If you have multiple serializer classes with the same requirement of filtering lots of attributes, you can apply the DRY principle in your solution by creating another serializer class which will inherit from ActiveModel::Serializer
. Put the above class method definition inside this new serializer and inherit all the serializers from this new one which have list of attributes with __c
.
class KeyFilterSerializer < ActiveModel::Serializer
class << self
def attributes(*attrs)
attrs.each do |attr|
options = {}
options[:key] = attr.to_s[0..-4].to_sym if attr.to_s.end_with?('__c')
attribute(attr, options)
end
end
end
end
class TestSerializer < KeyFilterSerializer
attributes :id, :name, :field_one__c, :field_two__c
end
class AnotherTestSerializer < KeyFilterSerializer
attributes :id, :name, :field_one__c, :field_two__c
end