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

Feature/adapter #612

Merged
merged 27 commits into from
Aug 31, 2014
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
f00fe55
* Rename NullAdapter to SimpleAdapter
Aug 27, 2014
56725b4
Add NullAdapater
Aug 27, 2014
6cc4fa0
* Configure adapter using ActiveModel::Serializer.config.adapter
Aug 27, 2014
553c470
Serializer should be available wiithing adapter to inspect attributes…
Aug 27, 2014
7b7d4d8
Test for SimpleAdapter#serializable_hash
Aug 27, 2014
2c7906e
Test for NullAdapter#serializable_hash
Aug 27, 2014
a6f9dae
Concrete adapter should provide serializable hash for Adapter#to_json…
Aug 27, 2014
b1f7a5c
Move Adapter.adapter_for to Serializer.adapter
Aug 27, 2014
fa4ee9d
Add Serializer#associations
Aug 27, 2014
466c7d5
Wrap association into Serializers
Aug 28, 2014
597765e
start implementing json_api adapter to understand how associations sh…
Aug 28, 2014
1b718b6
fix spelling
Aug 28, 2014
c1fdfc1
First try to implement ArraySerializer
Aug 28, 2014
85b4b85
Remove 1.9.3 from CI build as we dropped support
Aug 28, 2014
85ff812
Include Enumerable to ArraySerializer
Aug 28, 2014
3dd4928
* Do not ingerit array serializer from Serializer
Aug 29, 2014
6496b08
rename simple adapter to json
Aug 29, 2014
6bb4501
JsonApi adapter: serialize association
Aug 29, 2014
e45e5a8
Remove 'Adapter' suffix from adapters since they are in Adapter:: nam…
Aug 29, 2014
b4a313e
Merge remote-tracking branch 'upstream/master' into feature/adapter
Aug 29, 2014
1396093
Object.const_get differs on 2.0 and 2.1.2. So rescue from NameError
Aug 29, 2014
77847d7
User String#constantize instead of Object.const_get
Aug 29, 2014
7293072
Revert "Remove 1.9.3 from CI build as we dropped support"
Aug 29, 2014
ff37b62
test for json adapter
Aug 29, 2014
45a47a1
safe_constantize instead of rescue
Aug 29, 2014
258b595
clean up code
Aug 29, 2014
71a43a4
Pass options to associations
Aug 29, 2014
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
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,13 @@ by AMS. If you want to use a different adapter, such as a HalAdapter, you can
change this in an initializer:

```ruby
ActiveModel::Serializer.default_adapter = ActiveModel::Serializer::Adapter::HalAdapter
ActiveModel::Serializer.config.adapter = ActiveModel::Serializer::Adapter::HalAdapter
```

or

```ruby
ActiveModel::Serializer.config.adapter = :hal
```

You won't need to implement an adapter unless you wish to use a new format or
Expand Down
2 changes: 1 addition & 1 deletion lib/action_controller/serialization.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def _render_option_json(resource, options)
if serializer
# omg hax
object = serializer.new(resource)
adapter = ActiveModel::Serializer::Adapter::NullAdapter.new(object)
adapter = ActiveModel::Serializer.adapter.new(object)

super(adapter, options)
else
Expand Down
23 changes: 23 additions & 0 deletions lib/active_model/serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ class Serializer
extend ActiveSupport::Autoload
autoload :Configuration
autoload :ArraySerializer
autoload :Adapter
include Configuration

class << self
Expand Down Expand Up @@ -73,6 +74,24 @@ def self.serializer_for(resource)
end
end

def self.adapter
adapter_class = case config.adapter
when Symbol
class_name = "ActiveModel::Serializer::Adapter::#{config.adapter.to_s.classify}Adapter"
if Object.const_defined?(class_name)
Object.const_get(class_name)
end
when Class
config.adapter
end
unless adapter_class
valid_adapters = Adapter.constants.map { |klass| ":#{klass.to_s.sub('Adapter', '').downcase}" }
raise ArgumentError, "Unknown adapter: #{config.adapter}. Valid adapters are: #{valid_adapters}"
end

adapter_class
end

attr_accessor :object

def initialize(object)
Expand All @@ -84,5 +103,9 @@ def attributes
hash[name] = send(name)
end
end

def associations
self.class._associations.dup
Copy link
Author

Choose a reason for hiding this comment

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

should return serializers

end
end
end
23 changes: 23 additions & 0 deletions lib/active_model/serializer/adapter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module ActiveModel
class Serializer
class Adapter
extend ActiveSupport::Autoload
autoload :SimpleAdapter
autoload :NullAdapter

attr_reader :serializer

def initialize(serializer)
@serializer = serializer
end

def serializable_hash(options = {})
raise NotImplementedError, 'This is abstract method. Should be implemented at concrete adapter.'
Copy link
Contributor

Choose a reason for hiding this comment

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

"This is an abstract method."

and

"Should be implemented on the concrete adapter."

Copy link
Author

Choose a reason for hiding this comment

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

Thank you

end

def to_json(options={})
serializable_hash(options).to_json
end
end
end
end
12 changes: 3 additions & 9 deletions lib/active_model/serializer/adapter/null_adapter.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
module ActiveModel
class Serializer
class Adapter
class NullAdapter
def initialize(adapter)
@attributes = adapter.attributes
end

def to_json(options={})
@attributes.each_with_object({}) do |(attr, value), h|
h[attr] = value
end.to_json # FIXME: why does passing options here cause {}?
class NullAdapter < Adapter
def serializable_hash(options = {})
{}
end
end
end
Expand Down
13 changes: 13 additions & 0 deletions lib/active_model/serializer/adapter/simple_adapter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module ActiveModel
class Serializer
class Adapter
class SimpleAdapter < Adapter
def serializable_hash(options = {})
serializer.attributes.each_with_object({}) do |(attr, value), h|
h[attr] = value
end
end
end
end
end
end
1 change: 1 addition & 0 deletions lib/active_model/serializer/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module Configuration

included do |base|
base.config.array_serializer = ActiveModel::Serializer::ArraySerializer
base.config.adapter = :simple
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/active_model_serializers.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require "active_model"
require "active_model/serializer/version"
require "active_model/serializer"
require "active_model/serializer/adapter/null_adapter"
require "active_model/serializer/adapter/simple_adapter"

begin
require 'action_controller'
Expand Down
25 changes: 25 additions & 0 deletions test/adapter/null_adapter_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
require 'test_helper'

module ActiveModel
class Serializer
class Adapter
class NullAdapterTest < Minitest::Test
def setup
profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
serializer = ProfileSerializer.new(profile)

@adapter = NullAdapter.new(serializer)
end

def test_serializable_hash
assert_equal({}, @adapter.serializable_hash)
end

def test_it_returns_empty_json
assert_equal('{}', @adapter.to_json)
end
end
end
end
end

Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@
module ActiveModel
class Serializer
class Adapter
class NullAdapterTest < Minitest::Test
class SimpleAdapterTest < Minitest::Test
def setup
@profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
@profile_serializer = ProfileSerializer.new(@profile)

@adapter = NullAdapter.new(@profile_serializer)
@adapter = SimpleAdapter.new(@profile_serializer)
end

def test_null_adapter
def test_serializable_hash
assert_equal({name: 'Name 1', description: 'Description 1'}, @adapter.serializable_hash)
end

def test_simple_adapter
assert_equal('{"name":"Name 1","description":"Description 1"}',
@adapter.to_json)

Expand Down
23 changes: 23 additions & 0 deletions test/adapter_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
require 'test_helper'

module ActiveModel
class Serializer
class AdapterTest < Minitest::Test
def setup
profile = Profile.new
@serializer = ProfileSerializer.new(profile)
@adapter = ActiveModel::Serializer::Adapter.new(@serializer)
end

def test_serializable_hash_is_abstract_method
assert_raises(NotImplementedError) do
@adapter.serializable_hash(only: [:name])
end
end

def test_serializer
assert_equal @serializer, @adapter.serializer
end
end
end
end
50 changes: 50 additions & 0 deletions test/serializers/adapter_for_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
module ActiveModel
class Serializer
class AdapterForTest < Minitest::Test
def setup
@previous_adapter = ActiveModel::Serializer.config.adapter
end

def teardown
ActiveModel::Serializer.config.adapter = @previous_adapter
end

def test_returns_default_adapter
adapter = ActiveModel::Serializer.adapter
assert_equal ActiveModel::Serializer::Adapter::SimpleAdapter, adapter
end

def test_overwrite_adapter_with_symbol
ActiveModel::Serializer.config.adapter = :null

adapter = ActiveModel::Serializer.adapter
assert_equal ActiveModel::Serializer::Adapter::NullAdapter, adapter
ensure

end

def test_overwrite_adapter_with_class
ActiveModel::Serializer.config.adapter = ActiveModel::Serializer::Adapter::NullAdapter

adapter = ActiveModel::Serializer.adapter
assert_equal ActiveModel::Serializer::Adapter::NullAdapter, adapter
end

def test_raises_exception_if_invalid_symbol_given
ActiveModel::Serializer.config.adapter = :unknown

assert_raises ArgumentError do
ActiveModel::Serializer.adapter
end
end

def test_raises_exception_if_it_does_not_know_hot_to_infer_adapter
ActiveModel::Serializer.config.adapter = 42

assert_raises ArgumentError do
ActiveModel::Serializer.adapter
end
end
end
end
end
19 changes: 19 additions & 0 deletions test/serializers/associations_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,25 @@ def test_has_one

assert_equal({post: {type: :belongs_to, options: {}}}, @comment_serializer.class._associations)
end

def test_associations
@comment_serializer_class.class_eval do
belongs_to :post
has_many :comments
end

expected_associations = {
post: {
type: :belongs_to,
options: {}
},
comments: {
type: :has_many,
options: {}
},
}
assert_equal(expected_associations, @comment_serializer.associations)
end
end
end
end
4 changes: 4 additions & 0 deletions test/serializers/configuration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ class ConfigurationTest < Minitest::Test
def test_array_serializer
assert_equal ActiveModel::Serializer::ArraySerializer, ActiveModel::Serializer.config.array_serializer
end

def test_adapter
assert_equal :simple, ActiveModel::Serializer.config.adapter
end
end
end
end