-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
:only option on has_many not working #1943
Comments
(follows #1942 ) @TiagoCardoso1983 are you saying that Is this documented behavior on 0.10 somewhere? I don't recall seeing it. This feature is related to a host of other issues, and I can't seem to find the canonical one:
|
This was a working and documented feature in 0.9.x . I looked in the 0.10.x documentation and couldn't find it, so I guess it's maybe removed(?). Judging by the list and after having a superficial look on those, I guess I'm not the only one experiencing issues. Is version 1.x coming, so maybe breaking APIs will not happen unexpectedly? I've used the |
I have been trying to figure out the best way to do something similar. In my case, I have a class Category < ApplicationRecord
belongs_to :parent, class_name: 'Category', optional: true
has_many :children, class_name: 'Category'
end
For example, given the following sample data: Vehicles:
- Cars
- Trucks Serializing the {
"id": 1,
"name": "Vehicles",
"total": 800,
"children": [
{"id": 2, "name": "Cars", "total": 500},
{"id": 3, "name": "Trucks", "total": 300}
]
} Serializing the {
"id": 2,
"name": "Cars",
"total": 500,
"parent": {"id": 1, "name": "Vehicles"},
} In 0.9.5, my class CategorySerializer < ActiveModel::Serializer
attributes :id, :name, :total, :parent
has_many :children
def parent
# If there is a parent, serialize only id + name
CategorySerializer.new object.parent, only: %i(id name) if object.parent
end
end In 0.10.2, this stopped working (the nested call to I have managed to get it working again by changing the class CategorySerializer < ActiveModel::Serializer
attributes :id, :name, :total
has_many :children, unless: -> { object.children.empty? }
belongs_to :parent, if: -> { object.parent } do
{
id: object.parent.id,
name: object.parent.name
}
end
end But manually constructing a Instead of passing a block to the class CategorySerializer < ActiveModel::Serializer
attributes :id, :name, :total
has_many :children, unless: -> { object.children.empty? }
belongs_to :parent, if: -> { object.parent }, only: %i(id name)
end |
The truth behind the |
So is the recommendation therefore something like a nested serializer definition (for serializing a category within a category? class CategorySerializer < ActiveModel::Serializer
attributes :id, :name, :total
has_many :children, unless: -> { object.children.empty? }
belongs_to :parent, if: -> { object.parent }
# This serializer used for category.parent and category.children
class CategorySerializer < ActiveModel::Serializer
attributes :id, :name
end
end |
In your case, why not have |
I'm not so much concerned about the Here's the previous example again, without the class CategorySerializer < ActiveModel::Serializer
attributes :id, :name, :total
has_many :children
belongs_to :parent
# This serializer used for category.parent and category.children
class CategorySerializer < ActiveModel::Serializer
attributes :id, :name
end
end (Unless I misunderstood the point you were making; which is entirely possible... 😄 ) |
Oh sorry – I was questioning the concept itself of having different representations for objects of the same type within a document. Is it necessary for you not to have |
That's a fair point...in the examples I provided, I only included a single additional attribute ( In my actual code, however, there are a number of additional attributes (5 or 6) that I would want excluded when serializing the nested relations. Partly this is because I want to ship the smallest JSON down to the client as possible (in an extreme case of a And partly this is because some of those additional attributes are potentially expensive to calculate. For example, let's assume that class CategorySerializer < ActiveModel::Serializer
attributes :id, :name, :total
# ....
def total
# some non-trivial calculation here...
end
end Ideally I wouldn't want to incur the overhead of calculating the total for each nested child item if it would ultimately go unused. (I will admit that I haven't actually measured what the extra cost is of including those additional attributes, so one could argue that I'm guilty of premature optimization here). |
For the expensive attributes, I think the right solution would be caching. The reason I advocate against having different sets of fields for resources of the same type is that you do not have to subsequently fetch a "fuller" representation of a resource – once it has been fetched, you know all there is to know about it, and this makes keeping a local partial representation of your data in the client much easier. I understand it is not necessarily everybody's use case, but in that case, JSON API may also not be the best format there is, and an ad-hoc format may be more suitable (as JSON API is relatively verbose, in order to simply the use-case I mentioned above). All that being said, part of the features you want are in AMS 0.10, and I believe the rest is being discussed somewhere (can't remember where). |
Thanks @beauby, you make some good points there. I should note that in my case I'm using the It does seem to me that the direction AMS is heading is more and more towards JSON API as the primary use case, and for simple attribute serialization AMS may actually be overkill. I might be better off just crafting the appropriate For now, I think I'll pin my Gemfile to |
Oh, I'm sorry I missed that. Yeah, you are right, AMS is headed more and more towards JSON API. The main reason for that is that it is a well-defined format, whereas the In your case, I would probably use either an older version of AMS, as you suggested, or even use something like |
Expected behavior vs actual behavior
I have the following set in a serializer:
But instead of filtering all the other attributes, it returns them all. This was something that was working with version 0.9.3, but apparently it is not anymore in 0.10.2.
Is it a bug?
The text was updated successfully, but these errors were encountered: