mirror of
https://github.com/samsonjs/grape-active_model_serializers.git
synced 2026-03-25 08:45:55 +00:00
Recoded to use active_model_serializer parameter of models/arrays and added array support
This commit is contained in:
parent
a3416e51d4
commit
3b67bd5393
4 changed files with 130 additions and 45 deletions
|
|
@ -1,4 +1,5 @@
|
|||
require 'active_record'
|
||||
require 'pry'
|
||||
|
||||
module Grape
|
||||
module Formatter
|
||||
|
|
@ -10,40 +11,52 @@ module Grape
|
|||
|
||||
ActiveModelSerializers.infer_serializers = true
|
||||
|
||||
def call(object, env)
|
||||
@object = object
|
||||
@env = env
|
||||
@endpoint = env['api.endpoint']
|
||||
def call(resource, env)
|
||||
# @object = object
|
||||
options = env['api.endpoint'].options[:route_options]
|
||||
|
||||
if object.is_a? ActiveRecord::Base and active_model_serializer?
|
||||
options = endpoint.options[:route_options][:serializer_options] || {}
|
||||
active_model_serializer.new(object).as_json options
|
||||
serializer = serializer(endpoint, resource, options)
|
||||
|
||||
if serializer
|
||||
serializer.to_json
|
||||
else
|
||||
Grape::Formatter::Json.call object, env
|
||||
Grape::Formatter::Json.call resource, env
|
||||
end
|
||||
end
|
||||
|
||||
# options = endpoint.options[:route_options][:serializer_options] || {}
|
||||
# serializer.new(object, options).to_json
|
||||
# end
|
||||
|
||||
private
|
||||
|
||||
def active_model_serializer?
|
||||
!!active_model_serializer
|
||||
end
|
||||
def serializer(endpoint, resource, options)
|
||||
# default_options = controller.send(:default_serializer_options) || {}
|
||||
options = {} #default_options.merge(options || {})
|
||||
|
||||
def active_model_serializer
|
||||
route_options = endpoint.options[:route_options]
|
||||
# Infer serializer name if its not set
|
||||
if self.infer_serializers
|
||||
route_options[:serializer] = @object.class.name unless route_options.has_key? :serializer
|
||||
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
|
||||
|
||||
serializer = route_options[:serializer]
|
||||
|
||||
if serializer.instance_of? String or serializer.instance_of? Symbol
|
||||
name = "#{serializer.to_s.camelize}Serializer"
|
||||
serializer = Kernel.const_get(name)
|
||||
if options[:root] != false && serializer.root != false
|
||||
# the serializer for an Array is ActiveModel::ArraySerializer
|
||||
options[:root] ||= serializer.root || resource.first.class.name.downcase.pluralize
|
||||
end
|
||||
serializer
|
||||
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
|
||||
|
|
|
|||
74
lib/grape-active_model_serializers/twitter_example.rb
Normal file
74
lib/grape-active_model_serializers/twitter_example.rb
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
module Twitter
|
||||
class API < Grape::API
|
||||
|
||||
version 'v1', :using => :header, :vendor => 'twitter'
|
||||
format :json
|
||||
|
||||
helpers do
|
||||
def current_user
|
||||
@current_user ||= User.authorize!(env)
|
||||
end
|
||||
|
||||
def authenticate!
|
||||
error!('401 Unauthorized', 401) unless current_user
|
||||
end
|
||||
end
|
||||
|
||||
resource :statuses do
|
||||
|
||||
desc "Return a public timeline."
|
||||
get :public_timeline do
|
||||
Status.limit(20)
|
||||
end
|
||||
|
||||
desc "Return a personal timeline."
|
||||
get :home_timeline do
|
||||
authenticate!
|
||||
current_user.statuses.limit(20)
|
||||
end
|
||||
|
||||
desc "Return a status."
|
||||
params do
|
||||
requires :id, :type => Integer, :desc => "Status id."
|
||||
end
|
||||
get ':id' do
|
||||
Status.find(params[:id])
|
||||
end
|
||||
|
||||
desc "Create a status."
|
||||
params do
|
||||
requires :status, :type => String, :desc => "Your status."
|
||||
end
|
||||
post do
|
||||
authenticate!
|
||||
Status.create!({
|
||||
:user => current_user,
|
||||
:text => params[:status]
|
||||
})
|
||||
end
|
||||
|
||||
desc "Update a status."
|
||||
params do
|
||||
requires :id, :type => String, :desc => "Status ID."
|
||||
requires :status, :type => String, :desc => "Your status."
|
||||
end
|
||||
put ':id' do
|
||||
authenticate!
|
||||
current_user.statuses.find(params[:id]).update({
|
||||
:user => current_user,
|
||||
:text => params[:status]
|
||||
})
|
||||
end
|
||||
|
||||
desc "Delete a status."
|
||||
params do
|
||||
requires :id, :type => String, :desc => "Status ID."
|
||||
end
|
||||
delete ':id' do
|
||||
authenticate!
|
||||
current_user.statuses.find(params[:id]).destroy
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -27,10 +27,10 @@ describe Grape::ActiveModelSerializers do
|
|||
end
|
||||
|
||||
it "should respond with proper content-type" do
|
||||
subject.get("/home", :serializer => "user") do
|
||||
subject.get("/home/users", :serializer => "user") do
|
||||
{user: {first_name: "JR", last_name: "HE"}}
|
||||
end
|
||||
get("/home")
|
||||
get("/home/users")
|
||||
last_response.headers["Content-Type"].should == "application/json"
|
||||
end
|
||||
|
||||
|
|
@ -40,33 +40,30 @@ describe Grape::ActiveModelSerializers do
|
|||
end
|
||||
|
||||
get "/home"
|
||||
last_response.body.should == '{:user=>{:first_name=>"JR", :last_name=>"HE"}}'
|
||||
last_response.body.should == "{\"user\":{\"first_name\":\"JR\",\"last_name\":\"HE\"}}"
|
||||
end
|
||||
|
||||
context "serializer inference is disabled" do
|
||||
before do
|
||||
Grape::Formatter::ActiveModelSerializers.infer_serializers = false
|
||||
it "should serializer arrays of objects" do
|
||||
subject.get("/home") do
|
||||
user = User.new({first_name: 'JR', last_name: 'HE', email: 'contact@jrhe.co.uk'})
|
||||
[user, user]
|
||||
end
|
||||
|
||||
it "should NOT infer serializer when there is no serializer set" do
|
||||
subject.get("/home") do
|
||||
User.new({first_name: 'JR', last_name: 'HE', email: 'contact@jrhe.co.uk'})
|
||||
end
|
||||
|
||||
get "/home"
|
||||
last_response.body.should == "{\"user\":{\"created_at\":null,\"first_name\":\"JR\",\"id\":null,\"last_name\":\"HE\",\"updated_at\":null,\"username\":null}}"
|
||||
end
|
||||
get "/home"
|
||||
last_response.body.should == "{\"users\":[{\"first_name\":\"JR\",\"last_name\":\"HE\"},{\"first_name\":\"JR\",\"last_name\":\"HE\"}]}"
|
||||
end
|
||||
|
||||
[UserSerializer, 'user', :user].each do |serializer|
|
||||
it "should render using serializer (#{serializer})" do
|
||||
subject.get("/home", serializer: serializer) do
|
||||
User.new({first_name: 'JR', last_name: 'HE', email: 'contact@jrhe.co.uk'})
|
||||
end
|
||||
# [User2Serializer, 'user2', :user2].each do |serializer|
|
||||
# it "should render using serializer (#{serializer})" do
|
||||
# subject.get("/home", serializer: serializer) do
|
||||
# User.new({first_name: 'JR', last_name: 'HE', email: 'contact@jrhe.co.uk'})
|
||||
# end
|
||||
|
||||
# get "/home"
|
||||
# last_response.body.should == "{\"user\":{\"first_name\":\"JR\",\"last_name\":\"HE\"}}"
|
||||
# end
|
||||
# end
|
||||
|
||||
|
||||
get "/home"
|
||||
last_response.body.should == '{:user=>{:first_name=>"JR", :last_name=>"HE"}}'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ require 'rspec'
|
|||
require 'rack/test'
|
||||
require "pry"
|
||||
require 'nulldb_rspec'
|
||||
# require 'plymouth'
|
||||
|
||||
include NullDB::RSpec::NullifiedDatabase
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue