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

Custom adapters examples and tutorial on writing a new one #1317

Open
mooreniemi opened this issue Nov 3, 2015 · 12 comments
Open

Custom adapters examples and tutorial on writing a new one #1317

mooreniemi opened this issue Nov 3, 2015 · 12 comments

Comments

@mooreniemi
Copy link

No description provided.

@beauby
Copy link
Contributor

beauby commented Nov 3, 2015

Thanks for opening this issue. We should definitely have some docs guiding users through writing a custom adapter.

First thing, your adapter should inherit from ActiveModel::Serializer::Adapter::Base. Then you mainly have to define one method: serializable_hash (and possibly fragment_cache in case you want to support fragment caching, but let's get into this later).

class MyAdapter < ActiveModel::Serializer::Adapter::Base
  def serializable_hash
    # as you can see here: https://github.com/rails-api/active_model_serializers/blob/master/lib/active_model/serializer/adapter/base.rb#L12
    # your adapter instance will be provided with an instance of a serializer (for the root object/collection), and some options (`instance_options`)
    # + serializer.object will be the root object/collection,
    # + serializer.attributes will be the list of key/value for the attributes you are supposed to serialize
    # + serializer.associations will be the list of associations (key is the name, value is a serializer instance for the related resource)
    # your adapter's role will be to turn all that into a hash that represents the JSON document you want to output
    # Dummy example:
    serializer.object.to_h # in case your root object supports the `to_h` method.
  end
end

@mooreniemi
Copy link
Author

Thanks! I'll see about trying to flesh this out. Perhaps tangential, but will there be a strategy to submit adapters to those supported in the core lib? I saw JSON+API was added, and it might be cool to add a few other key competing hypermedia types.

@beauby
Copy link
Contributor

beauby commented Nov 3, 2015

Yeah, feel free to open a PR to add your adapter to AMS. If it looks good and there are other people interested we'll merge it. Note that we need traction to merge it not because we don't want it, but because we want to make sure there will be good support for it.

@mooreniemi
Copy link
Author

@beauby When defining this adapter, what's my best route to do it? Do I need to have a whole Rails project initialized and install AMS into it? Should I clone down AMS as a repo and do it in the adapter folder? I was hoping I could just write the adapter separately. But if I install the gem and require it into my file, I don't get access to:

main » ActiveModel::Serializer::Adapter
NameError: uninitialized constant ActiveModel::Serializer::Adapter

I only get access to:

main » ActiveModel::Serializer.constants
=> [:Association, :Config, :CONFIG, :VERSION, :Utils]

I'll try requiring the release candidate to see if that's the issue.

@beauby
Copy link
Contributor

beauby commented Nov 4, 2015

The easiest way is to build unit tests for your adapters (following those for other adapters).

@mooreniemi
Copy link
Author

Yep -- I just mean literally in what project, like could I do it independent of a full rails repo. When I switched to requiring the release candidate I see I have access to Adapter so I think that was all my problem. Just leaving these comments here in case anyone tries to follow my steps.

@beauby
Copy link
Contributor

beauby commented Nov 4, 2015

Just clone the AMS repo and add your tests within the test/ folder.

@mooreniemi
Copy link
Author

@beauby sure, I could do that. For now I'm just playing around in a separate gem/repo and requiring the release candidate in. We'll see how far I can go with that... :) https://github.com/mooreniemi/amsa-mason

@mooreniemi
Copy link
Author

@beauby Ok, next question: https://github.com/rails-api/active_model_serializers/blob/master/lib/active_model/serializer/adapter/base.rb#L17

How/where am I handing in _options and how are these different from instance_options?

@beauby
Copy link
Contributor

beauby commented Nov 5, 2015

@mooreniemi Short answer is: you shouldn't care about those _options (the ones provided to serializable_hash, as those are handled by rails and we can't really make any assumption about them). The options you should care about are the ones passed to the serializer and to the adapter (directly via AdapterClass.new(..., options) / SerializerClass.new(..., options) or indirectly via SerializableResource.new(resource, options) which are then dispatched to the serializer and adapter depending on this list).

These options can then be accessed inside your adapter/serializer via the instance_options method.

@mooreniemi
Copy link
Author

@beauby K. So I can just define def serializable_hash(*) to accept all args and be good, yah? Thanks again for your on-going support!

@beauby
Copy link
Contributor

beauby commented Nov 5, 2015

Yup, exactly.

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

2 participants