-
Notifications
You must be signed in to change notification settings - Fork 153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ability to "flatten" nested entities into parent (e.g. for CSV) #45
base: master
Are you sure you want to change the base?
Conversation
Models that use single-table inheritance will be cast as specific classes that don't always have the attribute defined as a method. Checking to see if the `object` responds like a Hash allows more flexibility to get raw column data. We raise an `ArgumentError` to indicate that the attribute may be invalid.
…ia :object option
else | ||
object.send(attribute) | ||
raise ArgumentError, ":attribute was unable to be found anywhere" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should probably be specialized as an AttributeNotFoundException
, with the attribute name as a field, then you don't need an English explanation.
This would need tests, README and CHANGELOG entries. And of course a passing build. Thanks for contributing! |
@dblock updated with docs and tests. |
@dblock updated the example in README |
@dblock Interestingly enough, we took that approach initially, and then wanted to try and utilize the Initially, we added an The solution was to flatten the entities by copying the exposures so that the schema would describe all attributes, regardless of format. However, the only thing that I wasn't able to implement cleanly in this feature (that we had in our initial hacked-together version of this), was appending " (CSV only)" to the end of each description -- which would indicate why some attributes don't always appear. You're right, we could simply flatten the data, but that didn't seem to be self-documenting enough and defeated the purpose of using Grape Entity for us :-/ |
I'd love to hear what others think of this - will leave it open for a bit. In the meantime you might want to squash the commits/rebase this PR. |
I stumbled upon this PR looking for that exact functionality. class ItemRevision
(...) # versioned attributes a, b, c
end
class Item
(...) # unversioned attributes x, y, z
has_many ItemRevisions
end
class ItemRevisionEntity < Grape::Entity
expose :a, :b, :c
end
class ItemEntity < Grape::Entity
expose :x, :y, :z
merge_with ItemRevisionEntity { object.current_revision }
expose :revisions, using: ItemRevisionEntity, if: {history: true}
end I.e., the versioning might be irrelevant for some public API and is therefore hidden by only including the current revision, while the revision entity might be useful on its own in other contexts. If I can help please let me know, I'll be using this one way or the other. |
I'll leave this open for a bit. FWIW, this morning my inclination is to merge this. |
PR allows make entity partials in grape-entity. 👍 class DuckOptionsEntity < Grape::Entity
expose :duck_specific_attribute
end
class DogOptionsEntity < Grape::Entity
expose :dog_specific_attribute
end
class AnimalEntity < Grape::Entity
expose :nickname, :type
merge_with DogOptionsEntity, if: lambda { |object,options| object.dog? }
merge_with DuckOptionsEntity, if: lambda { |object,options| object.duck? }
end Usage: present Animal.all, with: AnimalEntity Result [
{
"nickname": "puppy",
"type": "dog",
"dog_specific_attribute": "value"
},
{
"nickname": "scrooge",
"type": "duck",
"duck_specific_attribute": "value"
}
] Is there any way to make it with standard grape-enitity? |
I am still sitting on this, I'll take a close look. Would appreciate other people's opinion. Generally, I think I want to weed the "flatten" part out of this, the |
👍 on getting the |
@brianphillips Want to try and extract a |
This feature allows you to specify another entity to copy exposures from. It's useful when flattening a hierarchy for CSV. It also adds the
:object
option to exposures that can define an alternate object to get values from. (Specifying an alternate object is necessary when copying exposures because the exposures don't refer to the original entity/model anymore.)