活动模型序列化程序中的条件属性
Conditional attributes in Active Model Serializers
如何仅在某些条件为真时才呈现属性?
例如,我想在创建操作时呈现用户的令牌属性。
你可以覆盖attributes
方法,这里是一个简单的例子:
class Foo < ActiveModel::Serializer
attributes :id
def attributes(*args)
hash = super
hash[:last_name] = 'Bob' unless object.persisted?
hash
end
end
您可以先在序列化程序 'initialize' 方法上设置条件。这个条件可以从代码中的任何其他地方传递,包含在 'initialize' 作为第二个参数接受的选项散列中:
class SomeCustomSerializer < ActiveModel::Serializer
attributes :id, :attr1, :conditional_attr2, :conditional_attr2
def initialize(object, options={})
@condition = options[:condition].present? && options[:condition]
super(object, options)
end
def attributes(*args)
return super unless @condition #get all the attributes
attributes_to_remove = [:conditional_attr2, :conditional_attr2]
filtered = super.except(*attributes_to_remove)
filtered
end
end
在这种情况下,将始终传递 attr1,而如果条件为真,则隐藏条件属性。
您将在代码的其他任何地方获得此自定义序列化的结果,如下所示:
custom_serialized_object = SomeCustomSerializer.new(object_to_serialize, {:condition => true})
我希望这有用!
序列化器 options 已合并到 ActiveModel 序列化器中,现在可用(自 0.10 起)。
覆盖是个好主意,但如果您使用 super
,将在您删除所需内容之前计算属性。如果它对你没有影响,好的,但是当它对你有影响时,你可以使用它:
def attributes(options={})
attributes =
if options[:fields]
self.class._attributes & options[:fields]
else
self.class._attributes.dup
end
attributes.delete_if {|attr| attr == :attribute_name } if condition
attributes.each_with_object({}) do |name, hash|
unless self.class._fragmented
hash[name] = send(name)
else
hash[name] = self.class._fragmented.public_send(name)
end
end
end
ps: v0.10.0.rc3
在最新版本(0.10.x
)中,你也可以这样做:
class EntitySerializer < ActiveModel::Serializer
attributes :id, :created_at, :updated_at
attribute :conditional_attr, if: :condition?
def condition?
#condition code goes here
end
end
例如:
class UserSerializer < ActiveModel::Serializer
attributes :id, :username, :name, :email, :created_at, :updated_at
attribute :auth_token, if: :auth_token?
def created_at
object.created_at.to_i
end
def updated_at
object.updated_at.to_i
end
def auth_token?
true if object.auth_token
end
end
编辑( 建议):
此方法不适用于最新版本(0.10
)
0.8
版本更简单。您不必使用 if: :condition?
。相反,您可以使用以下约定来获得相同的结果。
class EntitySerializer < ActiveModel::Serializer
attributes :id, :created_at, :updated_at
attribute :conditional_attr
def include_conditional_attr?
#condition code goes here
end
end
上面的例子看起来像这样。
class UserSerializer < ActiveModel::Serializer
attributes :id, :username, :name, :email, :created_at, :updated_at
attribute :auth_token
def created_at
object.created_at.to_i
end
def updated_at
object.updated_at.to_i
end
def include_auth_token?
true if object.auth_token
end
end
有关详细信息,请参阅 0.8 documentation。
以下是如何将参数直接传递给序列化程序实例,并根据序列化程序声明中的这些参数 show 或 hide 属性.
它也适用于父子序列化程序。
控制器或父序列化器:
ActiveModelSerializers::SerializableResource.new(object.locations, {
each_serializer: PublicLocationSerializer,
params: {
show_title: true
},
})
带有条件的序列化器:
class PublicLocationSerializer < ActiveModel::Serializer
attributes :id, :latitude, :longitude, :title
def title
object.title if @instance_options[:params][:show_title]
end
end
如何仅在某些条件为真时才呈现属性?
例如,我想在创建操作时呈现用户的令牌属性。
你可以覆盖attributes
方法,这里是一个简单的例子:
class Foo < ActiveModel::Serializer
attributes :id
def attributes(*args)
hash = super
hash[:last_name] = 'Bob' unless object.persisted?
hash
end
end
您可以先在序列化程序 'initialize' 方法上设置条件。这个条件可以从代码中的任何其他地方传递,包含在 'initialize' 作为第二个参数接受的选项散列中:
class SomeCustomSerializer < ActiveModel::Serializer
attributes :id, :attr1, :conditional_attr2, :conditional_attr2
def initialize(object, options={})
@condition = options[:condition].present? && options[:condition]
super(object, options)
end
def attributes(*args)
return super unless @condition #get all the attributes
attributes_to_remove = [:conditional_attr2, :conditional_attr2]
filtered = super.except(*attributes_to_remove)
filtered
end
end
在这种情况下,将始终传递 attr1,而如果条件为真,则隐藏条件属性。
您将在代码的其他任何地方获得此自定义序列化的结果,如下所示:
custom_serialized_object = SomeCustomSerializer.new(object_to_serialize, {:condition => true})
我希望这有用!
序列化器 options 已合并到 ActiveModel 序列化器中,现在可用(自 0.10 起)。
覆盖是个好主意,但如果您使用 super
,将在您删除所需内容之前计算属性。如果它对你没有影响,好的,但是当它对你有影响时,你可以使用它:
def attributes(options={})
attributes =
if options[:fields]
self.class._attributes & options[:fields]
else
self.class._attributes.dup
end
attributes.delete_if {|attr| attr == :attribute_name } if condition
attributes.each_with_object({}) do |name, hash|
unless self.class._fragmented
hash[name] = send(name)
else
hash[name] = self.class._fragmented.public_send(name)
end
end
end
ps: v0.10.0.rc3
在最新版本(0.10.x
)中,你也可以这样做:
class EntitySerializer < ActiveModel::Serializer
attributes :id, :created_at, :updated_at
attribute :conditional_attr, if: :condition?
def condition?
#condition code goes here
end
end
例如:
class UserSerializer < ActiveModel::Serializer
attributes :id, :username, :name, :email, :created_at, :updated_at
attribute :auth_token, if: :auth_token?
def created_at
object.created_at.to_i
end
def updated_at
object.updated_at.to_i
end
def auth_token?
true if object.auth_token
end
end
编辑( 建议):
此方法不适用于最新版本(0.10
)
0.8
版本更简单。您不必使用 if: :condition?
。相反,您可以使用以下约定来获得相同的结果。
class EntitySerializer < ActiveModel::Serializer
attributes :id, :created_at, :updated_at
attribute :conditional_attr
def include_conditional_attr?
#condition code goes here
end
end
上面的例子看起来像这样。
class UserSerializer < ActiveModel::Serializer
attributes :id, :username, :name, :email, :created_at, :updated_at
attribute :auth_token
def created_at
object.created_at.to_i
end
def updated_at
object.updated_at.to_i
end
def include_auth_token?
true if object.auth_token
end
end
有关详细信息,请参阅 0.8 documentation。
以下是如何将参数直接传递给序列化程序实例,并根据序列化程序声明中的这些参数 show 或 hide 属性.
它也适用于父子序列化程序。
控制器或父序列化器:
ActiveModelSerializers::SerializableResource.new(object.locations, {
each_serializer: PublicLocationSerializer,
params: {
show_title: true
},
})
带有条件的序列化器:
class PublicLocationSerializer < ActiveModel::Serializer
attributes :id, :latitude, :longitude, :title
def title
object.title if @instance_options[:params][:show_title]
end
end