-
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
0.10.0.pre does not include meta in response #876
Comments
Same missing meta on 0.10.rc1 using the json adapter using any combination of single resource and the options root, status, each_serializer so I guess this test is broken https://github.com/rails-api/active_model_serializers/blob/1577969cb763/test/serializers/meta_test.rb |
I'm happy to submit this as a PR, but here's some stuff I wrote to get meta data included # Make the meta key just work
# {"items": [{}, {}], "meta": {} }
#
# Background:
# When Rails renders JSON, it calls the json renderer method
# "_render_with_renderer_#{key = json}"
# https://github.com/rails/rails/blob/8c2c1bccccb3ea1f22503a184429d94193a1d9aa/actionpack/lib/action_controller/metal/renderers.rb#L44-L45
# which is defined in AMS https://github.com/rails-api/active_model_serializers/blob/1577969cb76309d1f48c68facc73e44c49489744/lib/action_controller/serialization.rb#L36-L37
# It creates a serializer instance from the resource
# and then a serializer adapter from the serializer instance
# which it passes along.
# For some reason, AMS strips the root param from the serializer during render
# https://github.com/rails-api/active_model_serializers/blob/1577969cb76309d1f48c68facc73e44c49489744/lib/action_controller/serialization.rb#L39
# so that only the adapter gets the root option
# https://github.com/rails-api/active_model_serializers/blob/1577969cb76309d1f48c68facc73e44c49489744/lib/active_model/serializer.rb#L142-L161
# and since the adapter requires the serializer to have a root to output the meta tag
# https://github.com/rails-api/active_model_serializers/blob/1577969cb76309d1f48c68facc73e44c49489744/lib/active_model/serializer/adapter.rb#L81-L84
# it's never actually put out (by the JSON adapter)
#
# What doesn't work:
# Ref: https://github.com/rails-api/active_model_serializers/pull/166
#
# extending the adapter with
# def as_json(options = {})
# if meta && serializer.is_a?(ActiveModel::Serializer::ArraySerializer)
# serializer.root = true
# super
# else
# super
# end
# end
# serializes a collection as {"items": ["item": {}], "meta": {} }
# serializes a resource as {"items": {} }
#
# extending the adapter with
# def as_json(options = {})
# if meta
# serializer.root = true
# super
# else
# super
# end
# end
# serializes a collection as {"items": ["item": {}], "meta": {} }
# serializes a resource as {"items": {}, "meta": {} }
#
# We get some combination of the above with the vanilla JSON serializer
# and some combination of the below:
# ActiveModel::Serializer._root = true/nil
# ItemSerializer._root = true/nil
# ActiveModel::Serializer::ArraySerializer._root = true/nil
# ActiveSupport.on_load(:active_model_serializers) do
# self._root = true/nil
# end
# ActiveRecord::Base.include_root_in_json = true/false
# ActiveSupport.on_load(:active_record) do
# self.include_root_in_json = true/false
# end
#
# Using the json_api adapter does output the meta key correctly, but
# changes the resource root to "data", which we don't want
#
# Calling render with or without the root option doesn't help either
# render json: @json, root: root, meta: {}
# render json: @json, meta: {}
require "active_model/serializer/adapter/json"
class JsonMetaAdapter < ActiveModel::Serializer::Adapter::Json
# extends the AMS adapter #as_json method
# https://github.com/rails-api/active_model_serializers/blob/1577969cb7/lib/active_model/serializer/adapter.rb#L22-L24
# def as_json(options = {})
# hash = serializable_hash(options)
# include_meta(hash)
# end
#
# which is called by Rails at the last rendering step
# https://github.com/rails/rails/blob/4-2-stable/actionpack/lib/action_controller/metal/renderers.rb#L66-L128
# ref https://github.com/rails-api/active_model_serializers/issues/878#issuecomment-96073030
# json = json.as_json(options) if json.respond_to?(:as_json)
# json = JSON.pretty_generate(json, options)
def as_json(options = {})
if meta
if serializer.is_a?(ActiveModel::Serializer::ArraySerializer)
super.update(meta: meta)
else
serializer.root = true
super
end
else
super
end
end
end
ActiveModel::Serializer.config.adapter = JsonMetaAdapter |
👍 bump |
Meta are not rendered anymore with the def include_meta(json)
json[meta_key] = meta if meta && root
json
end And def initialize(objects, options = {})
options.merge!(root: nil) |
Why in 0.10 is not posible to include {
"data": [ ],
"meta": {
"pagination": {
"total_count": 475,
"total_pages": 10,
"total": 50,
"current_page": 1,
"per_page": 50
}
} Is this a bug or there is a good reason behind this? I'll be glad to help if you need something. |
Our v1 API requires this behavior. Our v2 is a jsonapi.org style api but I can't just suddenly convert the old stuff. I need meta on array responses. |
Here's what I'm using in an initializer to work around this. require 'active_model/serializer/adapter/json'
module ActiveModel
class Serializer
class Adapter
class JsonMeta < Json
def initialize(serializer, options = {})
super
serializer.root = true if @options[:root]
end
end
end
end
end
ActiveModel::Serializer.config.adapter = ActiveModel::Serializer::Adapter::JsonMeta Edit: This doesn't work for empty arrays. |
I took a stab at this in #915. |
Commit message, adding meta support:
As this change was implemented by @kurko I'm not comfortable about moving forward without hearing from him. IMO, add |
The issue seems to be that the base adapter and the json adapter use different logic to get the
This gets us meta back in the result when using the json adapter and specifying a root. The change has no visible impact on the json api adapter that I can see - it works as before the change. Happy to create a PR? |
I tested it here, it's seem to work, all tests are still passing, @chrisbranson make yourself comfortable to open a PR! I'll check it, other people may test it too and then we merge it. 😄 |
I'm happy to write a PR, too. I've been meaning to do it for a while, but I'll do it today unless @chrisbranson would like to (no toe stepping!) or we can work at https://github.com/rails-api/active_model_serializers/pull/915/files ? |
PR #936 created including a test |
@bf4 your branch has a lot more changes in different places to mine, so I created a new PR to keep it clean. |
@stevenwu looks like #936 is going to be the fix PR, good job @chrisbranson (btw, I didn't write the other pr I referenced) |
I was able to include meta info when I set
ActiveModel::Serializer.config.adapter = :json_api
. However, when I remove this option, there is nometa
in the response.meta
is included in the response once I switch to0.8.3
version.The text was updated successfully, but these errors were encountered: