我正在使用ROAR为Rails应用程序实现API。此应用程序处理的票证可以具有主题和描述等属性,但也可以具有用户定义的属性。为了简单起见,假设票证如下:

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


这样的票证所需的JSON输出如下所示:

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


现在您可能已经看到了问题。所有属性都是根对象的直接子代,这意味着我不能将其表示为代表:

class TicketRepresenter
  property :subject
  property :description

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


ROAR是否提供某种机制来实现这一目标?例如。在实际实例的上下文中执行的回调,例如

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


在ROAR中是否有我为实现此目的而被忽略的东西?

我同时查看了ROAR的文档和representable的文档,但是什么也找不到。

免责声明

我试图简化实际情况以使问题更易读。如果您认为缺少重要信息,请告诉我。值得庆幸的是,我将提供更多细节。

超出范围

请不要讨论所选的JSON格式是好是坏,我想评估一下ROAR是否会支持它。

最佳答案

我相信解决该问题的最佳方法是使用Roar的writer:。通过将少数几个调用选项的值传递给提供的lambda,它可以完全控制输出。

例如:

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


github自述文件未涵盖很多用途,但Trailblazer网站上已记录了这些用途。尤其可以在http://trailblazer.to/gems/representable/3.0/function-api.html#writer处找到该地址。

干杯!

08-26 15:05