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

Reimplement serialization scope and scope_name #811

Merged
merged 2 commits into from
Mar 10, 2015
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
20 changes: 20 additions & 0 deletions lib/action_controller/serialization.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ module Serialization

ADAPTER_OPTION_KEYS = [:include, :fields, :root, :adapter]

included do
class_attribute :_serialization_scope
self._serialization_scope = :current_user
end

def serialization_scope
send(_serialization_scope) if _serialization_scope &&
Copy link
Member

Choose a reason for hiding this comment

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

if possible, use public_send instead 😄

respond_to?(_serialization_scope, true)
end

def get_serializer(resource)
@_serializer ||= @_serializer_opts.delete(:serializer)
@_serializer ||= ActiveModel::Serializer.serializer_for(resource)
Expand All @@ -29,6 +39,10 @@ def use_adapter?
options.partition { |k, _| ADAPTER_OPTION_KEYS.include? k }.map { |h| Hash[h] }

if use_adapter? && (serializer = get_serializer(resource))

@_serializer_opts[:scope] ||= serialization_scope
@_serializer_opts[:scope_name] = _serialization_scope

# omg hax
object = serializer.new(resource, @_serializer_opts)
adapter = ActiveModel::Serializer::Adapter.create(object, @_adapter_opts)
Expand All @@ -38,5 +52,11 @@ def use_adapter?
end
end
end

module ClassMethods
def serialization_scope(scope)
self._serialization_scope = scope
end
end
end
end
16 changes: 12 additions & 4 deletions lib/active_model/serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,21 @@ def self.root_name
name.demodulize.underscore.sub(/_serializer$/, '') if name
end

attr_accessor :object, :root, :meta, :meta_key
attr_accessor :object, :root, :meta, :meta_key, :scope

def initialize(object, options = {})
@object = object
@root = options[:root] || (self.class._root ? self.class.root_name : false)
@meta = options[:meta]
@object = object
@root = options[:root] || (self.class._root ? self.class.root_name : false)
@meta = options[:meta]
@meta_key = options[:meta_key]
@scope = options[:scope]

scope_name = options[:scope_name]
if scope_name && !respond_to?(scope_name)
self.class.class_eval do
define_method scope_name, lambda { scope }
end
end
end

def json_key
Expand Down
67 changes: 67 additions & 0 deletions test/action_controller/serialization_scope_name_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
require 'test_helper'
require 'pathname'

class DefaultScopeNameTest < ActionController::TestCase
TestUser = Struct.new(:name, :admin)

class UserSerializer < ActiveModel::Serializer
attributes :admin?
def admin?
current_user.admin
end
end

class UserTestController < ActionController::Base
protect_from_forgery

before_filter { request.format = :json }

def current_user
TestUser.new('Pete', false)
end

def render_new_user
render json: TestUser.new('pete', false), serializer: UserSerializer, adapter: :json_api
end
end

tests UserTestController

def test_default_scope_name
get :render_new_user
assert_equal '{"users":{"admin?":false}}', @response.body
end
end

class SerializationScopeNameTest < ActionController::TestCase
TestUser = Struct.new(:name, :admin)

class AdminUserSerializer < ActiveModel::Serializer
attributes :admin?
def admin?
current_admin.admin
end
end

class AdminUserTestController < ActionController::Base
protect_from_forgery

serialization_scope :current_admin
before_filter { request.format = :json }

def current_admin
TestUser.new('Bob', true)
end

def render_new_user
render json: TestUser.new('pete', false), serializer: AdminUserSerializer, adapter: :json_api
end
end

tests AdminUserTestController

def test_override_scope_name_with_controller
get :render_new_user
assert_equal '{"admin_users":{"admin?":true}}', @response.body
end
end