Skip to content

Commit

Permalink
Merge 13337ee into cec7980
Browse files Browse the repository at this point in the history
  • Loading branch information
Steven Harman committed Jan 9, 2014
2 parents cec7980 + 13337ee commit c114496
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 3 deletions.
1 change: 1 addition & 0 deletions lib/action_controller/serialization.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ def build_json_serializer(resource, options = {})
if serializer = options.fetch(:serializer, ActiveModel::Serializer.serializer_for(resource))
options[:scope] = serialization_scope unless options.has_key?(:scope)
options[:resource_name] = controller_name if resource.respond_to?(:to_ary)
options[:url_generator] = ActiveModel::Serializer.url_generator(url_options)

serializer.new(resource, options)
end
Expand Down
4 changes: 3 additions & 1 deletion lib/active_model/array_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ def initialize(object, options={})
@meta = options[@meta_key]
@each_serializer = options[:each_serializer]
@resource_name = options[:resource_name]
@url_generator = options[:url_generator]
end
attr_accessor :object, :scope, :root, :meta_key, :meta
attr_reader :url_generator

def json_key
if root.nil?
Expand All @@ -33,7 +35,7 @@ def json_key

def serializer_for(item)
serializer_class = @each_serializer || Serializer.serializer_for(item) || DefaultSerializer
serializer_class.new(item, scope: scope)
serializer_class.new(item, scope: scope, url_generator: url_generator)
end

def serializable_object
Expand Down
13 changes: 12 additions & 1 deletion lib/active_model/serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
require 'active_model/serializable'
require 'active_model/serializer/associations'
require 'active_model/serializer/config'
require 'active_model/serializer/url_generator'

require 'thread'

Expand Down Expand Up @@ -60,6 +61,10 @@ def serializer_for(resource)
end
end

def url_generator(*args)
UrlGenerator.new(*args)
end

attr_accessor :_root, :_attributes, :_associations
alias root _root=
alias root= _root=
Expand Down Expand Up @@ -107,9 +112,13 @@ def initialize(object, options={})
@root = options.fetch(:root, self.class._root)
@meta_key = options[:meta_key] || :meta
@meta = options[@meta_key]
@url_generator = options[:url_generator]
@wrap_in_array = options[:_wrap_in_array]
end
attr_accessor :object, :scope, :root, :meta_key, :meta
attr_reader :url_generator

alias_method :urls, :url_generator

def json_key
if root == true || root.nil?
Expand Down Expand Up @@ -166,7 +175,7 @@ def embedded_in_root_associations

def build_serializer(association)
object = send(association.name)
association.build_serializer(object, scope: scope)
association.build_serializer(object, scope: scope, url_generator: url_generator)
end

def serialize(association)
Expand All @@ -190,4 +199,6 @@ def serializable_object(options={})
end
alias_method :serializable_hash, :serializable_object
end

ActiveSupport.run_load_hooks(:active_model_serializers, ActiveModel::Serializer)
end
8 changes: 7 additions & 1 deletion lib/active_model/serializer/railtie.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
module ActiveModel
class Railtie < Rails::Railtie
initializer 'generators' do |app|
initializer 'active_model_serializers.setup_generators' do |app|
app.load_generators
require 'active_model/serializer/generators/serializer/serializer_generator'
require 'active_model/serializer/generators/serializer/scaffold_controller_generator'
require 'active_model/serializer/generators/resource_override'
end

initializer 'active_model_serializers.include_url_helpers' do |app|
ActiveSupport.on_load(:active_model_serializers) do
::ActiveModel::Serializer::UrlGenerator.send :include, app.routes.url_helpers
end
end
end
end
15 changes: 15 additions & 0 deletions lib/active_model/serializer/url_generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module ActiveModel
class Serializer
class UrlGenerator

def initialize(current_url_options = {})
@current_url_options = current_url_options
end

def url_options
@url_options ||=
Hash(CONFIG.default_url_options).merge(@current_url_options)
end
end
end
end
21 changes: 21 additions & 0 deletions test/fixtures/poro.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ def comments
class Comment < Model
end

class Category < Model
def posts
@posts ||= [Post.new(title: 'First', body: 'Post 1'),
Post.new(title: 'Second', body: 'Post 2')]
end
end

###
## Serializers
###
Expand All @@ -59,6 +66,20 @@ class PostSerializer < ActiveModel::Serializer
has_many :comments
end

class HypermediaPostSerializer < PostSerializer
attributes :title, :body, :link

def link
urls.post_url
end
end

class CommentSerializer < ActiveModel::Serializer
attributes :content
end

class CategorySerializer < ActiveModel::Serializer
attributes :name

has_many :posts, serializer: HypermediaPostSerializer
end
17 changes: 17 additions & 0 deletions test/integration/action_controller/serialization_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,23 @@ def test_render_using_json_dump
end
end

class HypermediaSerializerTest < ActionController::TestCase
class MyController < ActionController::Base
def render_with_hypermedia_links
render json: Category.new(name: 'Welcome!')
end
end

tests MyController

def test_render_json_with_links
get :render_with_hypermedia_links
assert_equal 'application/json', @response.content_type
assert_match '"name":"Welcome!"', @response.body
assert_match '"link":"http://test.host/post"', @response.body
end
end

class RailsSerializerTest < ActionController::TestCase
class MyController < ActionController::Base
def render_using_rails_behavior
Expand Down
2 changes: 2 additions & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
module TestHelper
Routes = ActionDispatch::Routing::RouteSet.new
Routes.draw do
resource :post
get ':controller(/:action(/:id))'
get ':controller(/:action)'
end

ActionController::Base.send :include, Routes.url_helpers
ActiveModel::Serializer::UrlGenerator.send :include, Routes.url_helpers
end

ActionController::TestCase.class_eval do
Expand Down
49 changes: 49 additions & 0 deletions test/unit/active_model/serializer/url_generator_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
require 'test_helper'

module ActiveModel
class Serializer
class UrlGeneratorTest < ActiveModel::TestCase
def setup
@post = Post.new(title: 'Hi', body: 'How are you?')
@url_generator = UrlGenerator.new(host: 'example.com')
end

def test_url_generator_available
serializer = HypermediaPostSerializer.new(@post, url_generator: @url_generator)
serialized_post = serializer.as_json['hypermedia_post']

assert_equal(@url_generator, serializer.url_generator)
assert_equal('http://example.com/post', serialized_post[:link])
end

def test_url_generator_available_in_associations
category = Category.new(name: 'Welcome', posts: [@post])
serializer = CategorySerializer.new(category, url_generator: @url_generator)
serialized_post = serializer.associations[:posts].first

assert_equal('http://example.com/post', serialized_post[:link])
end
end

class UrlGeneratorDefaultsTest < ActiveModel::TestCase
def setup
@post = Post.new(title: 'Hi', body: 'How are you?')
@old_url_options = CONFIG.default_url_options
@url_generator = UrlGenerator.new
end

def test_url_generator_uses_default_url_options_from_config
CONFIG.default_url_options = {host: 'default.local'}
serializer = HypermediaPostSerializer.new(@post, url_generator: @url_generator)
serialized_post = serializer.as_json['hypermedia_post']

assert_equal('http://default.local/post', serialized_post[:link])
end

def teardown
CONFIG.default_url_options = @old_url_options
end
end
end
end

0 comments on commit c114496

Please sign in to comment.