一部の条件が真の場合にのみ属性をレンダリングするにはどうすればよいですか?
たとえば、作成アクションでユーザーのトークン属性をレンダリングしたいとします。
次のようにすることもできます:
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
詳細は .8ドキュメント を参照してください。
attributes
メソッドをオーバーライドできます。簡単な例を次に示します。
class Foo < ActiveModel::Serializer
attributes :id
def attributes(*args)
hash = super
hash[:last_name] = 'Bob' unless object.persisted?
hash
end
end
まず、シリアライザの 'initialize'メソッドに条件を設定します。この条件は、コードのどこからでも渡すことができ、「初期化」が2番目の引数として受け入れるオプションハッシュに含まれます。
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は常に渡されますが、条件がtrueの場合、条件付き属性は非表示になります。
次のように、コード内の他の場所でこのカスタムシリアル化の結果を取得します。
custom_serialized_object = SomeCustomSerializer.new(object_to_serialize, {:condition => true})
これがお役に立てば幸いです。
シリアライザ オプション は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