I ended up dynamically creating classes from my basic representer:
class TicketRepresenter property :subject property :description def self.create(ticket, context = {}) klass = Class.new(TicketRepresenter) # create a subclass of my representer ticket.custom_attributes.each do |attribute| # for each custom attribute in the actual instance insert a property into the created class property "customField#{attribute.id}".to_sym getter: -> (*) { attribute.value } end # return an instance of the class created above klass.new(ticket, context) endend
Basically that means the actual representer class used to create the JSON is a different one for each Ticket
.
If you wanted to read a Ticket
back from JSON, it is neccessary to correctly initialize the representer so that the created representer class knows about your custom fields and also define setters.
You will now need to conventionally call the new create
method instead of new
.If you need your representer to be created by ROAR (e.g. for a collection), you can use the Polymorphic Object Creation mechanism of ROAR.
Note: The code above does not exactly fit the example of custom attributes posted in my question, but you should get the idea (in the example an attribute did not have members like id
and value
, but was list consisting of key and value).