Merge pull request #4 from campaignio/master

Support for namespace options and rely more on active_model_serializers
This commit is contained in:
jrhe 2013-05-18 23:24:55 -07:00
commit b55a8586fe
10 changed files with 85 additions and 110 deletions

15
Gemfile
View file

@ -1,18 +1,3 @@
source 'https://rubygems.org'
gemspec
group :test do
gem "rspec", "~> 2.12.0"
gem "rack-test"
gem "rake"
gem "activerecord-nulldb-adapter"
end
group :development, :test do
gem "pry"
gem "pry-debugger"
gem "pry-rescue"
gem "pry-stack_explorer"
gem 'plymouth'
end

View file

@ -2,16 +2,12 @@ PATH
remote: .
specs:
grape-active_model_serializers (0.1.0)
active_model_serializers
activerecord
grape (~> 0.3)
i18n
tilt
GEM
remote: https://rubygems.org/
specs:
active_model_serializers (0.7.0)
active_model_serializers (0.8.1)
activemodel (>= 3.0)
activemodel (3.2.13)
activesupport (= 3.2.13)
@ -28,18 +24,7 @@ GEM
multi_json (~> 1.0)
arel (3.0.2)
backports (2.6.7)
binding_of_caller (0.7.1)
debug_inspector (>= 0.0.1)
builder (3.0.4)
coderay (1.0.9)
columnize (0.3.6)
debug_inspector (0.0.2)
debugger (1.5.0)
columnize (>= 0.3.1)
debugger-linecache (~> 1.2.0)
debugger-ruby_core_source (~> 1.2.0)
debugger-linecache (1.2.0)
debugger-ruby_core_source (1.2.0)
descendants_tracker (0.0.1)
diff-lcs (1.1.3)
grape (0.4.1)
@ -52,29 +37,10 @@ GEM
rack-accept
rack-mount
virtus
hashie (2.0.3)
hashie (2.0.5)
i18n (0.6.1)
interception (0.3)
method_source (0.8.1)
multi_json (1.7.2)
multi_json (1.7.3)
multi_xml (0.5.3)
plymouth (0.3.3)
pry-exception_explorer (~> 0.1.7)
pry (0.9.12)
coderay (~> 1.0.5)
method_source (~> 0.8)
slop (~> 3.4)
pry-debugger (0.2.2)
debugger (~> 1.3)
pry (~> 0.9.10)
pry-exception_explorer (0.1.9)
pry-stack_explorer (>= 0.3.9)
pry-rescue (1.1.0)
interception (>= 0.3)
pry
pry-stack_explorer (0.4.9)
binding_of_caller (>= 0.7)
pry (~> 0.9.11)
rack (1.5.2)
rack-accept (0.4.5)
rack (>= 0.4)
@ -91,8 +57,6 @@ GEM
rspec-expectations (2.12.1)
diff-lcs (~> 1.1.3)
rspec-mocks (2.12.2)
slop (3.4.4)
tilt (1.3.6)
tzinfo (0.3.37)
virtus (0.5.4)
backports (~> 2.6.1)
@ -102,13 +66,10 @@ PLATFORMS
ruby
DEPENDENCIES
active_model_serializers
activerecord
activerecord-nulldb-adapter
grape-active_model_serializers!
plymouth
pry
pry-debugger
pry-rescue
pry-stack_explorer
rack-test
rake
rspec (~> 2.12.0)

View file

@ -64,7 +64,7 @@ Grape::Formatter::ActiveModelSerializers.infer_serializers = false
```
### Manually specifying a serializer
### Manually specifying serializer options
Serializers can be specified at a route level by with the serializer option. A serializer can be specified by passing the the serializer class or the serializer name. The following are equivalent:
@ -81,6 +81,27 @@ get "/home", :serializer => :home
...
```
You can also set a serializer at the namespace level. This serializer can/will be overriden if a serilizer is also specified on the route.
```ruby
namespace 'foo', :serializer => :bar do
get "/" do
# will use "bar" serializer
end
get "/home", :serializer => :home do
# will use "home" serializer
end
end
```
Other standard options for `ActiveModel::Serializers` can be provided at either the namespace or route level with the same overriding behavior.
```ruby
get "/home", :root => 'world', :each_serializer => :fancy_home
...
```
### Example

View file

@ -16,8 +16,11 @@ Gem::Specification.new do |gem|
gem.version = Grape::ActiveModelSerializers::VERSION
gem.add_dependency "grape", "~> 0.3"
gem.add_dependency "activerecord"
gem.add_dependency "active_model_serializers"
gem.add_dependency "tilt"
gem.add_dependency "i18n"
gem.add_development_dependency "activerecord"
gem.add_development_dependency "active_model_serializers"
gem.add_development_dependency "rspec", "~> 2.12.0"
gem.add_development_dependency "rack-test"
gem.add_development_dependency "rake"
gem.add_development_dependency "activerecord-nulldb-adapter"
end

View file

@ -1,5 +1,5 @@
require 'active_model_serializers'
require 'grape'
require 'hashie/hash'
require 'grape/endpoint_extension'
require "grape-active_model_serializers/version"
require "grape-active_model_serializers/formatter"
require "grape-active_model_serializers/formatter"

View file

@ -1,21 +1,24 @@
require 'active_record'
require 'pry'
module Grape
module Formatter
module ActiveModelSerializers
class << self
attr_accessor :infer_serializers
attr_reader :env
attr_reader :endpoint
ActiveModelSerializers.infer_serializers = true
def call(resource, env)
# @object = object
options = env['api.endpoint'].options[:route_options]
@endpoint = env["api.endpoint"]
options = endpoint.namespace_options.merge(endpoint.route_options)
serializer = serializer(endpoint, resource, options)
if resource.is_a?(Array) && !resource.empty?
# ensure we have an root to fallback on
endpoint.controller_name = resource.first.class.name.underscore.pluralize
end
serializer = ::ActiveModel::Serializer.build_json(endpoint, resource, options)
if serializer
serializer.to_json
@ -23,41 +26,6 @@ module Grape
Grape::Formatter::Json.call resource, env
end
end
# options = endpoint.options[:route_options][:serializer_options] || {}
# serializer.new(object, options).to_json
# end
private
def serializer(endpoint, resource, options)
# default_options = controller.send(:default_serializer_options) || {}
options = {} #default_options.merge(options || {})
serializer = options.delete(:serializer) ||
(resource.respond_to?(:active_model_serializer) &&
resource.active_model_serializer)
return serializer unless serializer
if resource.respond_to?(:to_ary)
unless serializer <= ActiveModel::ArraySerializer
raise ArgumentError.new("#{serializer.name} is not an ArraySerializer. " +
"You may want to use the :each_serializer option instead.")
end
if options[:root] != false && serializer.root != false
# the serializer for an Array is ActiveModel::ArraySerializer
options[:root] ||= serializer.root || resource.first.class.name.underscore.pluralize
end
end
# options[:scope] = controller.serialization_scope unless options.has_key?(:scope)
# options[:scope_name] = controller._serialization_scope
# options[:url_options] = controller.url_options
serializer.new(resource, options)
end
end
end
end

View file

@ -1 +0,0 @@
require 'grape-active_model_serializers'

View file

@ -0,0 +1,26 @@
#
# Make the Grape::Endpoint quack like a ActionController
#
# This allows us to rely on the ActiveModel::Serializer#build_json method
# to lookup the approriate serializer.
#
module Grape
module EndpointExtension
attr_accessor :controller_name
def namespace_options
settings[:namespace] ? settings[:namespace].options : {}
end
def route_options
options[:route_options]
end
def default_serializer_options; end
def serialization_scope; end
def _serialization_scope; end
def url_options; end
end
Endpoint.send(:include, EndpointExtension)
end

View file

@ -1,5 +1,6 @@
require 'spec_helper'
require 'spec_fakes'
require "grape-active_model_serializers"
# require 'active_model'
describe Grape::ActiveModelSerializers do
@ -74,6 +75,17 @@ describe Grape::ActiveModelSerializers do
end
end
it "uses namespace options when provided" do
subject.namespace :admin, :serializer => UserSerializer do
get('/jeff') do
User.new(first_name: 'Jeff')
end
end
get "/admin/jeff"
last_response.body.should == "{\"user\":{\"first_name\":\"Jeff\",\"last_name\":null}}"
end
# [User2Serializer, 'user2', :user2].each do |serializer|
# it "should render using serializer (#{serializer})" do
# subject.get("/home", serializer: serializer) do

View file

@ -5,15 +5,15 @@ require 'bundler'
Bundler.setup :default, :test
require 'active_support/core_ext/hash/conversions'
require 'active_record'
require 'active_model'
require "active_model_serializers"
require "active_support/json"
require 'grape/active_model_serializers'
require 'rspec'
require 'rack/test'
require "pry"
ActiveRecord::Base.establish_connection :adapter => :nulldb, :schema => 'db/schema.rb'
require 'nulldb_rspec'
# require 'plymouth'
include NullDB::RSpec::NullifiedDatabase