扩展@ratbeard 的答案,以下适用于任何 active_model_serializer 0.9.x 及更高版本。我包含了使 PORO 可序列化散列对象与 rails 之外的 activemodel 序列化程序一起工作所需的最少量的 active_support 和 active_model 类。出于我的优化目的,我传入了一个预先计算的序列化对象数组,该数组在应用程序的其他地方计算。您可以重载 ActiveModel::Serializer 子类中的初始化程序,而不是重新计算,以便在可用时将其传递。
lib/serializable_hash.rb
class SerializableHash < Hash
alias :read_attribute_for_serialization :[]
end
应用程序/序列化程序/电子邮件/foo_serializer.rb
require 'active_model/serializer'
require 'active_support/core_ext/object'
require 'active_support/inflector'
require 'active_support/notifications'
class Email::FooSerializer < ActiveModel::Serializer
attributes :id, :bars, :created_at, :updated_at
def initialize(foo, precomputed_serialized_array_of_bars =nil)
unless serialized_bars
serialized_bars = {}
foo.bar.each do | bar |
serialized_searches[bar.baz] ||= []
serialized_searches[bar.baz] << Email::BarSerializer.new(bar).attributes
end
end
super(SerializableHash[
id: foo.id,
bars: serialized_bars,
created_at: foo.created_at
updated_at: foo.updated_at
])
end
end
为了完整起见,我还包括了这个使用实例变量而不是可序列化哈希的替代版本:
应用程序/序列化程序/电子邮件/foo_serializer.rb
require 'active_model/serializer'
require 'active_support/core_ext/object'
require 'active_support/inflector'
require 'active_support/notifications'
class Email::FooSerializer < ActiveModel::Serializer
attributes :id, :bars, :created_at, :updated_at
def initialize(foo, precomputed_serialized_array_of_bars=nil)
@bars = precomputed_serialized_array_of_bars
super(foo)
end
def bars
if @bars
return @bars
else
serialized_bars = {}
object.bars.each do | bar |
serialized_bars[bar.baz] ||= []
serialized_bars[bar.baz] << Email::BarSerializer.new(bar).attributes
end
return serialized_bars
end
end
end
然后使用序列化顶级对象,您只需执行
require 'app/serializers/email/foo_serializer'
require 'app/serializers/email/bar_serializer'
Email::FooSerializer.new(Foo.first).as_json
或者,如果您想使用预先计算的序列化条形数组:
# pre-compute array_of_serialized_bars somewhere up here
require 'app/serializers/email/foo_serializer'
require 'app/serializers/email/bar_serializer'
Email::FooSerializer.new(Foo.first, array_of_pre_serialized_bars).as_json