Skip to content

upgrade doc #1290

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

Closed
wants to merge 6 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions docs/howto/UPGRADING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# How to upgrade from previous versions

### Creating a Custom Base Adapter

You can upgrade to ams ``.10`` by creating a custom Base Adapter to
emulate the response that your application currently serves.

###### Base Adapter

A base adapter takes a ``ActiveModel::Serializer`` or
``ActiveModel::Serializer::ArraySerializer`` instance, and creates a hash
used for serialization in its ``serializable_hash`` method. A base adapter
could look like this:

```ruby
class MyApp::BaseAdapter < ActiveModel::Serializer::Adapter::Base
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: ;:. why not try adding this code with tests?

I'm thinking

# lib/active_model_serializers/v08/serializer.rb
# lib/active_model_serializers/v08/collection_serializer.rb
# lib/active_model_serializers/v08/adapter.rb
module ActiveModelSerializers::V08
  # Serializer might not need anything, but good to have defined
  Serializer = ActiveModel::Serializer
  CollectionSerializer = ActiveModel::Serializer::CollectionSerializer # well, it's Array now, but hopefully we'll get that renaming pr soon
  class Adapter < ActiveModel::Serializer::Adapter::Base
    # whatever methods you need
  end
end

And test like the other serializers and adapters

adapter = :'v08/adapter'
serializer = :'v08/array_serializer'
each_serializer = :'v08/serializer'
collection_resource = Post.all
expected_response = [{ something }]
assert ActiveModel::SerializableResource.new(collection_resource, serializer: serializer, each_serializer: each_serializer, adapter: adapter).as_json, expected_response

# and

adapter = :'v08/adapter'
serializer = :'v08/serializer'
resource = Post.first
expected_response = { something }
assert ActiveModel::SerializableResource.new(collection_resource, serializer: serializer, adapter: adapter).as_json, expected_response

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though after clicking comment, I realized the options definitions are wrong, should be:

adapter = ActiveModelSerializers::V08::Adapter
serializer = ActiveModelSerializers::V08::ArraySerializer
each_serializer = ActiveModelSerializers::V08::Serializer

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rails-api/ams thoughts on naming, folder etc?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

anything specific? looks ok to me :-\ (except for the crazy long asserts)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the API for the serializer itself changes (namely the root option). How should I address that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bf4:

typo: ;:. why not try adding this code with tests?

sorry I must be blind, I don't see the typo.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code blind
Semicolon in place of colon

Way i wrote was ambiguous

B mobile phone

On Oct 22, 2015, at 12:02 PM, Nick notifications@github.com wrote:

In docs/howto/UPGRADING.md:

+# How to upgrade from previous versions
+
+### Creating a Custom Base Adapter
+
+You can upgrade to ams .10 by creating a custom Base Adapter to
+emulate the response that your application currently serves.
+
+###### Base Adapter
+
+A base adapter takes a ActiveModel::Serializer or
+ActiveModel::Serializer::ArraySerializer instance, and creates a hash
+used for serialization in its serializable_hash method. A base adapter
+could look like this:
+
+```ruby
+class MyApp::BaseAdapter < ActiveModel::Serializer::Adapter::Base
@bf4:

typo: ;:. why not try adding this code with tests?

sorry I must be blind, I don't see the typo.


Reply to this email directly or view it on GitHub.

def serializable_hash(options=nil)
options ||= {}

if serializer.respond_to?(:each)
serializable_hash_for_collection(options)
else
serializable_hash_for_single_resource(options)
end
end

def serializable_hash_for_collection(options)
serializer.map do |s|
MyApp::BaseAdapter.new(s, instance_options).serializable_hash(options)
end
end

def serializable_hash_for_single_resource(options)
hash[:data] = serializer.attributes.merge(type: type)
end

private

# serializer is the passed in serializer defined in the Base class.
def type
serializer.object.class.name.demodulize.underscore
end
end
```

Now in your controller, you can use the adapter in the call to ``render``,
e.g.

```ruby
class PostController < ActionController::Base
def index
render Post.all, adapter: MyApp::BaseAdapter
end

def show
render Post.find(params[:id]), adapter: MyApp::BaseAdapter
end
end
```

When testing for the JSON output in a request or controller spec, you can use
something like the following in your tests:

```ruby
let(:post) { Post.create! }
let(:get_json) do
MyApp::BaseAdapter.new(PostSerializer.new(post)).to_json
end

let(:index_json) do
MyApp::CollectionAdapter.new(
ActiveModel::Serializer::ArraySerializer.new(
[post]
)
).to_json
end

RSpec.describe PostController do
it 'returns the expected json for index' do
get :index, format: :json
expect(response.body).to eq index_json
end

it 'returns the expected json for show' do
get :show, id: post.id, format: :json
expect(response.body).to eq get_json
end
end
```

> After you upgrade to AMS ``.10``, you can now use the recommended JSON API
> serialization for new endpoints, and if you choose, convert existing
> endpoints to the new standard one by one.