Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dynamically add properties to a ROAR representer?

I am using ROAR to implement an API for a rails application. This application deals with tickets that can have attributes like a subject and a description, but also have user defined attributes. For simplicity lets assume a ticket looks like:

class Ticket
  attr_accessor :subject, :description

  def custom_attributes
    # in reality these attributes depend on the current ticket instance
    # they are not hard-coded into the class
    [['priority', 'high'], ['Operating System', 'Ubuntu']]
  end
end

The desired JSON output for such a ticket looks as follows:

{
  "subject": "Foo",
  "description": "Bar",
  "customField1": "high",
  "customField2": "Ubuntu"
}

Now you might already see the problem. All properties are immediate children of the root object, this means I can't write that up as representer:

class TicketRepresenter
  property :subject
  property :description

  # Need to iterate over instance members on the class level here...
end

Is there some mechanic that ROAR offers to accomplish that? E.g. a callback that is executed in the context of an actual instance, e.g.

def call_me_on_write
  represented.custom_attributes.each do |attribute|
    add_property('customField1', attribute[1])
  end
end

Is there something like this in ROAR that I have overlooked to accomplish this?

I looked in both the docs for ROAR and the docs for representable, but could not find anything.

Disclaimer

I tried to simplify the actual circumstances to make the question more readable. If you think that important information are missing, please tell me. I will thankfully provide more details.

Out of scope

Please do not discuss whether the chosen JSON format is a good/bad idea, I want to evaluate whether ROAR would support it.

like image 579
NobodysNightmare Avatar asked Dec 10 '25 06:12

NobodysNightmare


1 Answers

I believe the best approach for the problem would be to use Roar's writer:. It completely turns control over the output to you by passing a handful of values it calls options to a provided lambda.

For example:

property :desired_property_name, writer: -> (represented:, doc:, **) do
  doc[:desired_key] = represented.desired_value
end

There are a lot of uses not covered by the github readme but which are documented on the Trailblazer website. This one in particular can be found at http://trailblazer.to/gems/representable/3.0/function-api.html#writer.

Cheers!

like image 86
Chico Carvalho Avatar answered Dec 11 '25 21:12

Chico Carvalho



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!