Skip to content
Merged
Show file tree
Hide file tree
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
4 changes: 3 additions & 1 deletion lib/active_model/serializable_resource.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
require "set"
require 'set'
Copy link
Member

Choose a reason for hiding this comment

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

👍

module ActiveModel
class SerializableResource

Expand Down Expand Up @@ -76,7 +76,9 @@ def serializer?

private

ActiveModelSerializers.silence_warnings do
attr_reader :resource, :adapter_opts, :serializer_opts
end

end
end
5 changes: 3 additions & 2 deletions lib/active_model/serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class Serializer
autoload :Adapter
autoload :Lint
autoload :Associations
autoload :Fieldset
include Configuration
include Associations

Expand Down Expand Up @@ -66,10 +67,10 @@ def self.attribute(attr, options = {})
@_attributes_keys[attr] = { key: key } if key != attr
@_attributes << key unless @_attributes.include?(key)

unless respond_to?(key, false) || _fragmented.respond_to?(attr)
ActiveModelSerializers.silence_warnings do
define_method key do
object.read_attribute_for_serialization(attr)
end
end unless respond_to?(key, false) || _fragmented.respond_to?(attr)
end
end

Expand Down
29 changes: 14 additions & 15 deletions lib/active_model/serializer/adapter.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
require 'active_model/serializer/adapter/fragment_cache'

module ActiveModel
class Serializer
class Adapter
extend ActiveSupport::Autoload
autoload :Json
require 'active_model/serializer/adapter/json'
require 'active_model/serializer/adapter/json_api'
autoload :FlattenJson
autoload :Null
autoload :JsonApi
autoload :FragmentCache
Copy link
Member

Choose a reason for hiding this comment

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

👍


def self.create(resource, options = {})
override = options.delete(:adapter)
klass = override ? adapter_class(override) : ActiveModel::Serializer.adapter
klass.new(resource, options)
end

def self.adapter_class(adapter)
adapter_name = adapter.to_s.classify.sub("API", "Api")
"ActiveModel::Serializer::Adapter::#{adapter_name}".safe_constantize
end

attr_reader :serializer

Expand All @@ -26,17 +36,6 @@ def as_json(options = nil)
hash
end

def self.create(resource, options = {})
override = options.delete(:adapter)
klass = override ? adapter_class(override) : ActiveModel::Serializer.adapter
klass.new(resource, options)
end

def self.adapter_class(adapter)
adapter_name = adapter.to_s.classify.sub("API", "Api")
"ActiveModel::Serializer::Adapter::#{adapter_name}".safe_constantize
end

def fragment_cache(*args)
raise NotImplementedError, 'This is an abstract method. Should be implemented at the concrete adapter.'
end
Expand Down
3 changes: 2 additions & 1 deletion lib/active_model/serializer/adapter/json/fragment_cache.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'active_model/serializer/adapter/fragment_cache'
module ActiveModel
class Serializer
class Adapter
Expand All @@ -12,4 +13,4 @@ def fragment_cache(cached_hash, non_cached_hash)
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'active_model/serializer/adapter/fragment_cache'
module ActiveModel
class Serializer
class Adapter
Expand All @@ -20,4 +21,4 @@ def fragment_cache(root, cached_hash, non_cached_hash)
end
end
end
end
end
8 changes: 3 additions & 5 deletions lib/active_model/serializer/associations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,9 @@ def has_one(name, options = {})
def associate(reflection)
self._reflections = _reflections.dup

unless method_defined?(reflection.name)
define_method reflection.name do
object.send reflection.name
end
end
define_method reflection.name do
object.send reflection.name
end unless method_defined?(reflection.name)
Copy link
Member

Choose a reason for hiding this comment

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

👍


self._reflections << reflection
end
Expand Down
4 changes: 3 additions & 1 deletion lib/active_model/serializer/fieldset.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ def fields_for(serializer)

private

ActiveModelSerializers.silence_warnings do
attr_reader :raw_fields, :root
end

def parsed_fields
if raw_fields.is_a?(Hash)
Expand All @@ -37,4 +39,4 @@ def parsed_fields

end
end
end
end
13 changes: 12 additions & 1 deletion lib/active_model_serializers.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
module ActiveModelSerializers
module_function

def silence_warnings
verbose = $VERBOSE
$VERBOSE = nil
yield
ensure
$VERBOSE = verbose
end

end
Copy link
Member Author

Choose a reason for hiding this comment

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

required because of a Ruby bug or as a 'safety valve' for unfixable or not-worth-fixing warnings. such is life

e.g.

  private

  ActiveModelSerializers.silence_warnings do
    attr_reader :resource, :adapter_opts, :serializer_opts
  end

require 'active_model'
require 'active_model/serializer/version'
require 'active_model/serializer'
require 'active_model/serializer/fieldset'
require 'active_model/serializable_resource'

begin
Expand Down
14 changes: 9 additions & 5 deletions test/action_controller/serialization_scope_name_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
class DefaultScopeNameTest < ActionController::TestCase
class UserSerializer < ActiveModel::Serializer
attributes :admin?
def admin?
current_user.admin
ActiveModelSerializers.silence_warnings do
def admin?
current_user.admin
end
Copy link
Member Author

Choose a reason for hiding this comment

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

I couldn't figure out how to get around this 'method redefined?' warning. I think Rails silences these kind of warnings as well.

end
end

Expand Down Expand Up @@ -34,8 +36,10 @@ def test_default_scope_name
class SerializationScopeNameTest < ActionController::TestCase
class AdminUserSerializer < ActiveModel::Serializer
attributes :admin?
def admin?
current_admin.admin
ActiveModelSerializers.silence_warnings do
def admin?
current_admin.admin
end
end
end

Expand All @@ -60,4 +64,4 @@ def test_override_scope_name_with_controller
get :render_new_user
assert_equal '{"data":{"id":"1","type":"users","attributes":{"admin?":true}}}', @response.body
end
end
end
11 changes: 6 additions & 5 deletions test/action_controller/serialization_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ def render_fragment_changed_object_with_except_cache_enabled
def render_fragment_changed_object_with_relationship
comment = Comment.new({ id: 1, body: 'ZOMG A COMMENT' })
comment2 = Comment.new({ id: 1, body: 'ZOMG AN UPDATED-BUT-NOT-CACHE-EXPIRED COMMENT' })
author = Author.new(id: 1, name: 'Joao Moura.')
like = Like.new({ id: 1, likeable: comment, time: 3.days.ago })

generate_cached_serializer(like)
Expand Down Expand Up @@ -215,14 +214,16 @@ def test_render_json_object_without_serializer
get :render_json_object_without_serializer

assert_equal 'application/json', @response.content_type
assert_equal ({error: 'Result is Invalid'}).to_json, @response.body
expected_body = {error: 'Result is Invalid'}
assert_equal expected_body.to_json, @response.body
end

def test_render_json_array_object_without_serializer
get :render_json_array_object_without_serializer

assert_equal 'application/json', @response.content_type
assert_equal ([{error: 'Result is Invalid'}]).to_json, @response.body
expected_body = [{error: 'Result is Invalid'}]
assert_equal expected_body.to_json, @response.body
end

def test_render_array_using_implicit_serializer
Expand Down Expand Up @@ -405,9 +406,9 @@ def use_adapter?
false
end
}.new
assert_match /adapter: false/, (capture(:stderr) {
assert_match(/adapter: false/, (capture(:stderr) {
controller.get_serializer(Profile.new)
})
}))
end

def test_dont_warn_overridding_use_adapter_as_truthy_on_controller_instance
Expand Down
1 change: 0 additions & 1 deletion test/adapter/json/belongs_to_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ def setup
@comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
@post.comments = [@comment]
@anonymous_post.comments = []
@post.author = @author
@comment.post = @post
@comment.author = nil
@anonymous_post.author = nil
Expand Down
2 changes: 1 addition & 1 deletion test/capture_warnings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def before_tests

def after_tests
stderr_file.rewind
lines = stderr_file.read.split("\n").uniq
lines = stderr_file.read.split("\n")
stderr_file.close!

$stderr.reopen(STDERR)
Expand Down
9 changes: 3 additions & 6 deletions test/fixtures/poro.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
verbose = $VERBOSE
$VERBOSE = nil
class Model
FILE_DIGEST = Digest::MD5.hexdigest(File.open(__FILE__).read)

Expand Down Expand Up @@ -260,9 +262,4 @@ def maker
cache only: [:id]
attributes :id
end

RaiseErrorSerializer = Class.new(ActiveModel::Serializer) do
def json_key
raise StandardError, 'Intentional error for rescue_from test'
end
end
$VERBOSE = verbose
Copy link
Member Author

Choose a reason for hiding this comment

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

this file was just full of warnings that aren't really that important and were really hard to fix, mostly due to all the dynamic class generation.

4 changes: 2 additions & 2 deletions test/generators/serializer_generator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ def test_with_no_attributes_does_not_add_extra_space
run_generator ["account"]
assert_file "app/serializers/account_serializer.rb" do |content|
if RUBY_PLATFORM =~ /mingw/
assert_no_match /\r\n\r\nend/, content
assert_no_match(/\r\n\r\nend/, content)
else
assert_no_match /\n\nend/, content
assert_no_match(/\n\nend/, content)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion test/serializers/associations_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def test_has_many_with_no_serializer
def test_serializer_options_are_passed_into_associations_serializers
association = @post_serializer
.associations
.detect { |association| association.key == :comments }
.detect { |assoc| assoc.key == :comments }

assert association.serializer.first.custom_options[:custom_options]
end
Expand Down
8 changes: 4 additions & 4 deletions test/serializers/cache_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ def test_cache_key_definition
end

def test_cache_key_interpolation_with_updated_at
author = render_object_with_cache(@author)
render_object_with_cache(@author)
Copy link
Member

Choose a reason for hiding this comment

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

👍

assert_equal(nil, ActionController::Base.cache_store.fetch(@author.cache_key))
assert_equal(@author_serializer.attributes.to_json, ActionController::Base.cache_store.fetch("#{@author_serializer.class._cache_key}/#{@author_serializer.object.id}-#{@author_serializer.object.updated_at.strftime("%Y%m%d%H%M%S%9N")}").to_json)
end

def test_default_cache_key_fallback
comment = render_object_with_cache(@comment)
render_object_with_cache(@comment)
assert_equal(@comment_serializer.attributes.to_json, ActionController::Base.cache_store.fetch(@comment.cache_key).to_json)
end

Expand All @@ -74,7 +74,7 @@ def test_associations_separately_cache
assert_equal(nil, ActionController::Base.cache_store.fetch(@comment.cache_key))

Timecop.freeze(Time.now) do
post = render_object_with_cache(@post)
render_object_with_cache(@post)

assert_equal(@post_serializer.attributes, ActionController::Base.cache_store.fetch(@post.cache_key))
assert_equal(@comment_serializer.attributes, ActionController::Base.cache_store.fetch(@comment.cache_key))
Expand Down Expand Up @@ -122,7 +122,7 @@ def test_fragment_fetch_with_virtual_associations
end

def test_uses_file_digest_in_cache_key
blog = render_object_with_cache(@blog)
render_object_with_cache(@blog)
assert_equal(@blog_serializer.attributes, ActionController::Base.cache_store.fetch(@blog.cache_key_with_digest))
end

Expand Down
21 changes: 21 additions & 0 deletions test/support/rails_app.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class Foo < Rails::Application
if Rails::VERSION::MAJOR >= 4
config.eager_load = false
config.secret_key_base = 'abc123'
config.action_controller.perform_caching = true
config.active_support.test_order = :random
config.logger = Logger.new(nil)
ActionController::Base.cache_store = :memory_store
end
end
Foo.initialize!

module TestHelper
Routes = ActionDispatch::Routing::RouteSet.new
Routes.draw do
get ':controller(/:action(/:id))'
get ':controller(/:action)'
end

ActionController::Base.send :include, Routes.url_helpers
end
49 changes: 49 additions & 0 deletions test/support/stream_capture.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Use cleaner stream testing interface from Rails 5 if available
# see https://github.com/rails/rails/blob/29959eb59d/activesupport/lib/active_support/testing/stream.rb
begin
require "active_support/testing/stream"
rescue LoadError
module ActiveSupport
module Testing
module Stream #:nodoc:
private

def silence_stream(stream)
old_stream = stream.dup
stream.reopen(IO::NULL)
stream.sync = true
yield
ensure
stream.reopen(old_stream)
old_stream.close
end

def quietly
silence_stream(STDOUT) do
silence_stream(STDERR) do
yield
end
end
end

def capture(stream)
stream = stream.to_s
captured_stream = Tempfile.new(stream)
stream_io = eval("$#{stream}")
origin_stream = stream_io.dup
stream_io.reopen(captured_stream)

yield

stream_io.rewind
return captured_stream.read
ensure
captured_stream.close
captured_stream.unlink
stream_io.reopen(origin_stream)
end
end
end
end
end

5 changes: 5 additions & 0 deletions test/support/test_case.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ActionController::TestCase.class_eval do
def setup
@routes = TestHelper::Routes
end
end
Loading