如何在序列化中将jsonb字段值视为一流属性?

时间:2019-02-17 13:41:52

标签: ruby-on-rails ruby serialization json-api fastjsonapi

我有一个使用postgresql jsonb字段的Rails后端。我想使用宝石fast_jsonapi,但尚未结婚。

我有一个jsonb字段,几乎是我要序列化的模型。但是,我还没有弄清楚如何创建它们的json属性(将它们序列化为一等公民)。因此,代替:

{  
   "attributes":{  
      "data":{  
         "title":"ok",
         "author":"masta p"
      },
      "created_at":"2019-02-16T17:40:21.477Z",
      "updated_at":"2019-02-16T17:40:21.477Z"
   }
}

我不需要额外的“数据”名称空间,并且希望它是:

{  
   "attributes":{  
      "title":"ok",
      "author":"masta p"
      "created_at":"2019-02-16T17:40:21.477Z",
      "updated_at":"2019-02-16T17:40:21.477Z"
   }
}

这样做的低成本方式是什么?

1 个答案:

答案 0 :(得分:1)

对于fast_jsonapi,这是不可能的。在序列化程序类中声明的每个属性都分派到活动记录对象。您将看到here,该库如何序列化给定对象。

因此,如果您要序列化jsonb对象为第一公民,我认为您有2种方法。首先,您将扩展FastJsonapi::Attribute类,然后覆盖serialize方法。但由于这种方法确实容易出错,因此我不建议这样做。

第二种方法是从jsonb对象中显式声明字段。为方便起见,以下解决方法适合您的问题。

class TestSerializer
  include FastJsonapi::ObjectSerializer

  JSONB_ATTRIBUTES = %i[title author review_count]
  JSONB_ATTRIBUTES.each do |attr|
    attribute attr do |object|
      object.data[attr.to_s] if object.data # Protection againts nil value
    end
  end
end

这比扩展序列化程序类要好得多。