Skip to content
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

Cannot control root option at serializer level anymore in 0.10.0rc5 #1683

Closed
bolthar opened this issue Apr 14, 2016 · 12 comments
Closed

Cannot control root option at serializer level anymore in 0.10.0rc5 #1683

bolthar opened this issue Apr 14, 2016 · 12 comments

Comments

@bolthar
Copy link

bolthar commented Apr 14, 2016

In 0.8, it was possible to determine if the serializer should include a root element or not via the root option, like so:

class MySerializer < ActiveModel::Serializer
  self.root = (((true or false)))
end

This has been removed in 0.10, and setting self.config.adapter = :attributes instead does nothing. Actually, it seems that the settings at the class level are ignored altogether.

By taking a look at https://github.com/rails-api/active_model_serializers/blob/master/lib/active_model/serializer/configuration.rb , one would expect that it should be possible to change the settings at the class level (there's even a comment that mentions it), but it doesn't seem to be possible. The options hash on classes deriving from ActiveModel::Serializeris always empty ({}), while I would have expected to see the default values in it. If I do something like:

class MyTestClass 
  include ActiveModel::Serializer::Configuration
end

then MyTestClass.confighas the expected values in it.

I can change the settings in an initializer, but that's global.

Would it be possible to change the root behavior at the class level again?

@bolthar bolthar changed the title Cannot control root options at serializer level anymore in 0.10.0rc5 Cannot control root option at serializer level anymore in 0.10.0rc5 Apr 14, 2016
@bf4
Copy link
Member

bf4 commented Apr 14, 2016

Would you mind clarifying what you expect the root option to be doing and how you're trying to use it. Please review the issue template so you can help me help you.

@HParker
Copy link

HParker commented Apr 14, 2016

I think I should be able to add some additional detail.

Expected behavior vs actual behavior

Expected

in a serializer, self.config.adapter = :json would set the configured_adapter for that serializer.

Actual

self.config.adapter = :json is ignored and instead the default is taken from ActiveModelSerializer.config.adapter

Steps to reproduce

On, 0.10.0.rc5,
Define a serializer:

class MySerializer < ActiveModel::Serializer
  self.config.adapter = :json
end

Use it:

serializer = MySerializer.new(profile)
adapter = ActiveModel::Serializer::Adapter.create(serializer)
adapter.as_json

See that there is no root key set.

Environment

Rails 4.2.3

  • ruby 2.2.1p85 (2015-02-26 revision 49769) [x86_64-linux]

ActiveModelSerializers Version (commit ref if not on tag):

  • 0.10.0.rc5

Output of ruby -e "puts RUBY_DESCRIPTION":

  • ruby 2.2.1p85 (2015-02-26 revision 49769) [x86_64-linux]

OS Type & Version:

  • gnu/linux (ubuntu)

Integrated application and version (e.g., Rails, Grape, etc):

  • Rails 4.2.3

Backtrace

(e.g., provide any applicable backtraces from your application)

  • N/A

Additonal helpful information

This is basically a request for discussion around setting the default adapter in the serializer. Right now this does not seem possible.

I work with @bolthar and we are describing the same issue.

@bf4
Copy link
Member

bf4 commented Apr 14, 2016

Ah, got it. I honestly didn't even consider that was an API a serializer instance would use.

I've actually been meaning to move it off the serializer class entirely as I thought of it as a misplaced global config

How would you image it working with associations when it belongs to another serializer or has one or more? If no adapter option passed into SerializableResource then it has an affect only when it is a top level resource?

B mobile phone

On Apr 14, 2016, at 6:05 PM, Adam Hess notifications@github.com wrote:

I think I should be able to add some additional detail.

Expected behavior vs actual behavior

Expected

in a serializer, self.config.adapter = :json would set the configured_adapter for that serializer.

Actual

self.config.adapter = :json is ignored and instead the default is taken from ActiveModelSerializer.config.adapter

Steps to reproduce

On, 0.10.0.rc5,
Define a serializer:

class MySerializer < ActiveModel::Serializer
self.config.adapter = :json
end
Use it:

serializer = MySerializer.new(profile)
adapter = ActiveModel::Serializer::Adapter.create(serializer)
adapter.as_json
See that there is no root key set.

Environment

Rails 4.2.3

ruby 2.2.1p85 (2015-02-26 revision 49769) [x86_64-linux]
ActiveModelSerializers Version (commit ref if not on tag):

0.10.0.rc5
Output of ruby -e "puts RUBY_DESCRIPTION":

ruby 2.2.1p85 (2015-02-26 revision 49769) [x86_64-linux]
OS Type & Version:

gnu/linux (ubuntu)
Integrated application and version (e.g., Rails, Grape, etc):

Rails 4.2.3
Backtrace

(e.g., provide any applicable backtraces from your application)

N/A
Additonal helpful information

This is basically a request for discussion around setting the default adapter in the serializer. Right now this does not seem possible.

I work with @bolthar and we are describing the same issue.


You are receiving this because you commented.
Reply to this email directly or view it on GitHub

@HParker
Copy link

HParker commented Apr 14, 2016

I honestly didn't even consider that was an API a serializer instance would use.

Yeah, in principle I agree with you. It is more of an adapter concern than a serializer concern.
However, right now we have some serializers that set self.root = false and some that set self.root = true.
Is there a way to get similar behavior in 0.10.0.rc5?

How would you image it working with associations when it belongs to another serializer or has one or more?

I imagine it would work the same way root did, which, I believe is what you are describing above. The Serializer specific config would only be used when it is not otherwise specified.

@bf4
Copy link
Member

bf4 commented Apr 15, 2016

So, if it helps, attributes adapter basically means no root, and json means yes root...

Would you mind sharing a complete (pseudocode ok) example where a serializer would be the place to configure serialization default? I'm having a hard time imagining, partly out of separation of concerns and partly just as a simple option or method override

B mobile phone

On Apr 14, 2016, at 6:54 PM, Adam Hess notifications@github.com wrote:

I honestly didn't even consider that was an API a serializer instance would use.

Yeah, in principle I agree with you. It is more of an adapter concern than a serializer concern.
However, right now we have some serializers that set self.root = false and some that set self.root = true.
Is there a way to get similar behavior in 0.10.0.rc5?

How would you image it working with associations when it belongs to another serializer or has one or more?

I imagine it would work the same way root did, which, I believe is what you are describing above. The Serializer specific config would only be used when it is not otherwise specified.


You are receiving this because you commented.
Reply to this email directly or view it on GitHub

@HParker
Copy link

HParker commented Apr 15, 2016

Totally.

So I have a serializer running on 0.8.x like,

class MySerializer < ActiveModel::Serializer
  attributes :id, :name
  self.root = true
end

which outputs:
{ my_serializer: {...} } (with a root)

and another,

class MyOtherSerializer < ActiveModel::Serializer
  attributes :id, :eye_color
  self.root = false
end

which outputs:
{...} (without a root)

After updating to 0.10.0.rc5, I am able to set the ActiveModelSerializer.config.adapter in an initializer, but I am unable to give a default to each serializer individually.

The only work around I could think of is calling render json: MyThing, adapter: :<adapter> where <adapter> is the adapter for that serializer in all of the places where that serializer is used.

To be clear, I think we already have a great interface for changing the adapter from the controller or at the instance level. A helpful addition would be a default at the class level.

config.adapter is already available in the serializer, but it is not looked at when looking up the adapter.

Is that the detail you were looking for?

@beauby
Copy link
Contributor

beauby commented Apr 17, 2016

You are correct that the current "right" way is via the render's adapter option. The current architecture of AMS is somewhat based on the idea that serializers are adapter-agnostic, so there is little probability that the feature you're requesting will be implemented.

@beauby
Copy link
Contributor

beauby commented Apr 20, 2016

Closing this for now, but let's keep talking about workarounds here.

@beauby beauby closed this as completed Apr 20, 2016
@HParker
Copy link

HParker commented Apr 20, 2016

Sounds good. Thank you!

Right now we are looking into how hard it will be to track down all the places serializers with root are used.

I really appreciate your help.

@bf4
Copy link
Member

bf4 commented Apr 20, 2016

Right now we are looking into how hard it will be to track down all the places serializers with root are used.

you mean in 0.10? or in your code? In rc1 I once listed a bunch #936 (comment) but they're not true anymore

@bf4
Copy link
Member

bf4 commented Apr 20, 2016

@HParker Any upgrade notes you can share back here as comments or a PR would be much appreciated!

@HParker
Copy link

HParker commented Apr 20, 2016

@bf4 I mean in our code. I am hoping we can find an easy way to move to the new standard while still feeling confident our external API is the same.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants