【问题标题】:Include IDs of nested associations in ActiveModel serializers在 ActiveModel 序列化程序中包含嵌套关联的 ID
【发布时间】:2017-02-06 18:33:35
【问题描述】:

在某些情况下,嵌套关联嵌入在 JSON 中,而在其他情况下则不是。到目前为止一切顺利,这符合我想要的方式。但我希望在没有嵌入它们的情况下仍然发出嵌套关联的 ID。

例如:

class FooSerializer < ActiveModel::Serializer
    attributes :id, :x, :y
    belongs_to :bar
end

class BarSerializer < ActiveModel::Serializer
    attributes :id, :z
end

当我序列化一个没有include: [:bar]Foo 对象时,我希望结果如下所示:

{
    "id": 123
    "x": 1,
    "y": 2,
    "bar": 456
}

如果bar 是一个多态关联,我想要这样的东西:

{
    "id": 123
    "x": 1,
    "y": 2,
    "bar": {"id": 456, "schema": "Bar"}
}

实际上,我希望 ID 是字符串 ("id": "123"),因为它们应该是 API 使用者的黑盒,并且绝对不使用 JavaScript 的 Number 类型(这是 double 精度浮点!)。

我该怎么做?我没有找到任何相关信息。

【问题讨论】:

    标签: ruby-on-rails json active-model-serializers


    【解决方案1】:

    在 FooSerializer 中以这种方式定义属性 id 以将其作为字符串获取:

    attribute :id do
      object.to_s
    end
    

    “当我序列化一个没有包含的 Foo 对象时:[:bar] 我希望结果看起来像:”

    attribute :bar do 
      object.bar.id.to_s
    end
    

    “如果 bar 是一个多态关联,我想要这样的东西:”

    attribute :bar do 
      {id: object.barable_id.to_s, schema: object.barable_type}
    end
    

    注意:我尚未对此进行测试。

    【讨论】:

    • 是的,就是那部分,我确实在BaseSerializer 中放了类似的东西。但是剩下的呢?
    • 但是我不能在一个中心位置执行此操作,而无需在我们的数十个序列化程序中一次又一次地编写此代码,每个序列化程序都有多个关系吗?
    • 不知道有没有这样的全局设置。我能想到的唯一方法是猴子修补我不推荐的 gem 类。
    【解决方案2】:

    我找到了一种使用BaseSerializer 的方法,如下所示:

    class BaseSerializer < ActiveModel::Serializer
        attributes :id, :type
    
        def id
            if object.id.nil?
                nil
            else
                object.id.to_s
            end
        end
    
        def type
            # I also want all the emitted objects to include a "type" field.
            object.class.name
        end
    
        def self.belongs_to(key, *args, &block)
            attribute key do
                assoc = object.class.reflect_on_association(key)
                foreign_id = object.send(assoc.foreign_key)
                if foreign_id.nil?
                    nil
                elsif assoc.polymorphic?
                    {
                        type: object.send(assoc.foreign_type),
                        id: foreign_id.to_s
                    }
                else
                    foreign_id.to_s
                end
            end
    
            super
        end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-01
      • 1970-01-01
      • 2017-11-01
      • 2015-07-20
      • 1970-01-01
      • 2017-01-29
      • 2019-05-21
      • 2016-07-28
      相关资源
      最近更新 更多