如何只在满足一些条件时才渲染属性?
例如,在创建操作中,我想要渲染用户的token属性。
如何只在满足一些条件时才渲染属性?
例如,在创建操作中,我想要渲染用户的token属性。
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文档获取更多详情。
attribute :foo, if: :bar
。只需为要有条件显示的每个属性命名一个函数,例如:include_foo?
,并在那里进行布尔检查即可。这些文档已经链接在答案中了。 - Joe Esseyinclude_foo?
方法似乎已被删除 -- 你仍然可以向属性方法添加一个 if: foo?
参数。 - RonLugge您可以覆盖attributes
方法,以下是一个简单的示例:
class Foo < ActiveModel::Serializer
attributes :id
def attributes(*args)
hash = super
hash[:last_name] = 'Bob' unless object.persisted?
hash
end
end
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
custom_serialized_object = SomeCustomSerializer.new(object_to_serialize, {:condition => true})
覆盖是个不错的想法,但如果你使用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
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
方法。 - apneadiving