diff --git a/lib/grape-active_model_serializers/formatter.rb b/lib/grape-active_model_serializers/formatter.rb index 148cd06..32aec4f 100644 --- a/lib/grape-active_model_serializers/formatter.rb +++ b/lib/grape-active_model_serializers/formatter.rb @@ -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 diff --git a/lib/grape-active_model_serializers/twitter_example.rb b/lib/grape-active_model_serializers/twitter_example.rb new file mode 100644 index 0000000..f571b66 --- /dev/null +++ b/lib/grape-active_model_serializers/twitter_example.rb @@ -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 \ No newline at end of file diff --git a/spec/grape_ams_spec.rb b/spec/grape_ams_spec.rb index 7a649c9..7c03c96 100644 --- a/spec/grape_ams_spec.rb +++ b/spec/grape_ams_spec.rb @@ -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 diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 239ae5f..32a1f2b 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -13,6 +13,7 @@ require 'rspec' require 'rack/test' require "pry" require 'nulldb_rspec' +# require 'plymouth' include NullDB::RSpec::NullifiedDatabase