grape-entity
grape-entity copied to clipboard
Deep merging of nested exposures and presenter exposures (with :using option)
Suppose this case:
class GeneralInfo < Grape::Entity
expose :gender, :age
end
class Student < Grape::Entity
expose :info, using: GeneralInfo
expose :info do
expose :grade
end
end
Student.represent({info: { gender: 'male', age: 25 }, grade: 5 }, serializable: true)
# => {:info=>{:grade=>5}}
But I assume info[:gender]
and info[:age]
to be exposed too. Also:
class Person < Grape::Entity
expose :info do
expose(:gender) { |obj| object[:info][:gender] }
expose(:age) { |obj| object[:info][:age] }
end
end
class Student < Person
expose :info do
expose :grade
end
end
Student.represent({info: { gender: 'male', age: 25 }, grade: 5 }, serializable: true)
# => {:info=>{:gender=>"male", :age=>25, :grade=>5}}
Since we decided not to rewrite previously defined exposures in #151 then more consistent behavior would be make these cases act identical. It's good to think of presenter exposures (with :using
option) as a nested exposures incapsulated in the separate classes.
Ones who want an old rewriting behavior should use conditional exposures (:if
, :unless
options).
On the other hand I expect from exposures that emit plain Hash
values a rewriting behavior:
class Something < Grape::Entity
expose :info do
expose :x
expose :y
end
expose :info do |obj, opts|
{ z: 123 }
end
end
Something.represent({ x: 1, y: 2 }, serializable: true)
# => {:info=>{:z=>123}}
This is because second :info
exposure is not nesting despite the fact that it exposes a hash too.
But maybe it's a not so useful feature as I think. There's also a problem with what to do if represent
returns an Array
of entities. The possibility of emitting an array makes this feature counterintuitive.
It's also very problematic to implement so I don't plan to do it in #151. Maybe later I'll rethink it.