From 1d2b6de7eaed7ec108f3b8efab727dd0c4b77be4 Mon Sep 17 00:00:00 2001 From: jrhe Date: Thu, 4 Apr 2013 20:10:51 +0100 Subject: [PATCH] Initial commit --- .DS_Store | Bin 0 -> 6148 bytes Gemfile | 15 +++ Gemfile.lock | 94 +++++++++++++ LICENSE | 0 README.md | 125 ++++++++++++++++++ Rakefile | 11 ++ grape-active_model_serializers.gemspec | 23 ++++ lib/.rspec | 2 + lib/.travis.yml | 8 ++ lib/grape-active_model_serializers.rb | 5 + .../formatter.rb | 50 +++++++ lib/grape-active_model_serializers/version.rb | 5 + lib/grape/active_model_serializers.rb | 1 + spec/.DS_Store | Bin 0 -> 6148 bytes spec/db/schema.rb | 10 ++ spec/grape_ams_spec.rb | 58 ++++++++ spec/schema.rb | 10 ++ spec/spec_fakes.rb | 9 ++ spec/spec_helper.rb | 29 ++++ 19 files changed, 455 insertions(+) create mode 100644 .DS_Store create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 LICENSE create mode 100644 README.md create mode 100644 Rakefile create mode 100644 grape-active_model_serializers.gemspec create mode 100644 lib/.rspec create mode 100644 lib/.travis.yml create mode 100644 lib/grape-active_model_serializers.rb create mode 100644 lib/grape-active_model_serializers/formatter.rb create mode 100644 lib/grape-active_model_serializers/version.rb create mode 100644 lib/grape/active_model_serializers.rb create mode 100644 spec/.DS_Store create mode 100644 spec/db/schema.rb create mode 100644 spec/grape_ams_spec.rb create mode 100644 spec/schema.rb create mode 100644 spec/spec_fakes.rb create mode 100644 spec/spec_helper.rb diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..55a3d3f63cb7e01f7e15ffb21a91aa6aee812fc6 GIT binary patch literal 6148 zcmeHKO-sW-5S?wKrhY&!qQ}K^k!XeX;30$x9)%Wqu%d}6G*Ft-r1TI|SdV0uh@7;XIv$qa?)f zoALd2ptW0&!UP8J_;vl^WE7{F>%NOh)!N$LvF%-Zzu$|;Q8M?F**HpXJHuq&iK9Un zOz#xWf^3%h!Blx}f^3K$#k)x|Lf$vgy*SE-_s&tCx6a+VY`8^T=FKM3i$<#`YBjs& zyxNB+rt|4sqg zA0#$H&tR!hZ5`OD5&+S{X=TW%mY^JI&@)(SL=T$KsfapNm=Z(ibexwa&NEnQ)af8h z@gdBcKZ_Tk-j2_gDjbBTk$YBv6O!BQhVh2~W{B3}fQAl$J6KcK(| DQD;Is literal 0 HcmV?d00001 diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..6c66fc8 --- /dev/null +++ b/Gemfile @@ -0,0 +1,15 @@ +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 do + gem "pry" + gem "debugger" +end diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..829f6a3 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,94 @@ +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) + activemodel (>= 3.0) + activemodel (3.2.13) + activesupport (= 3.2.13) + builder (~> 3.0.0) + activerecord (3.2.13) + activemodel (= 3.2.13) + activesupport (= 3.2.13) + arel (~> 3.0.2) + tzinfo (~> 0.3.29) + activerecord-nulldb-adapter (0.2.3) + activerecord (>= 2.0.0) + activesupport (3.2.13) + i18n (= 0.6.1) + multi_json (~> 1.0) + arel (3.0.2) + backports (2.6.7) + builder (3.0.4) + coderay (1.0.9) + columnize (0.3.6) + 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) + activesupport + builder + hashie (>= 1.2.0) + multi_json (>= 1.3.2) + multi_xml (>= 0.5.2) + rack (>= 1.3.0) + rack-accept + rack-mount + virtus + hashie (2.0.3) + i18n (0.6.1) + method_source (0.8.1) + multi_json (1.7.2) + multi_xml (0.5.3) + pry (0.9.12) + coderay (~> 1.0.5) + method_source (~> 0.8) + slop (~> 3.4) + rack (1.5.2) + rack-accept (0.4.5) + rack (>= 0.4) + rack-mount (0.8.3) + rack (>= 1.0.0) + rack-test (0.6.2) + rack (>= 1.0) + rake (10.0.4) + rspec (2.12.0) + rspec-core (~> 2.12.0) + rspec-expectations (~> 2.12.0) + rspec-mocks (~> 2.12.0) + rspec-core (2.12.2) + 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) + descendants_tracker (~> 0.0.1) + +PLATFORMS + ruby + +DEPENDENCIES + activerecord-nulldb-adapter + debugger + grape-active_model_serializers! + pry + rack-test + rake + rspec (~> 2.12.0) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md new file mode 100644 index 0000000..3301621 --- /dev/null +++ b/README.md @@ -0,0 +1,125 @@ +# Grape::ActiveModelSerializers + +Use [active_model_serializers](https://github.com/rails-api/active_model_serializers) with [Grape](https://github.com/intridea/grape)! + +[![Build Status](https://secure.travis-ci.org/jrhe/grape-active.png)](http://travis-ci.org/jrhe/grape-active_model_serializers) [![Dependency Status](https://gemnasium.com/jrhe/grape-active_model_serializers.png)](https://gemnasium.com/jrhe/grape-active_model_serializers) + + +## Installation + +Add the `grape` and `grape-active_model_serializers` gems to Gemfile. + +```ruby +gem 'grape' +gem 'grape-active_model_serializers' +``` + +And then execute: + + bundle + +## Usage + +### Require grape-active_model_serializers + +```ruby +# config.ru +require 'grape/active_model_serializers' +``` + + +### Tell your API to use Grape::Formatter::ActiveModelSerializers + +```ruby +class API < Grape::API + format :json + formatter :json, Grape::Formatter::ActiveModelSerializers +end +``` + + +### Writing serializers + +See [active_model_serializers](https://github.com/rails-api/active_model_serializers) + + +### Serializers are inferred by active_record model names + +grape-active_model_serializers will search for serializers for the objects returned by your grape API. + +Serializer +```ruby +namespace :users do + get ":id" do + @user = User.find(params[:id]) + end +end +``` +In this case, as User objects are being returned, grape-active_model_serializers will look for a serializer named UserSerializer. + +### Disabling serializer inferrence + +You can turn off serializer inferrence. +```ruby +Grape::Formatter::ActiveModelSerializers.infer_serializers = false +``` + + +### Manually specifying a serializer + +Serializers can be specified at a route level by with the serializer option. A serializer can be specified with its class name or by name as string/symbol. The following are equivalent: + +```ruby +get "/home", :serializer => HomeSerializer +... +``` +```ruby +get "/home", :serializer => "home" + +``` +```ruby +get "/home", :serializer => :home +``` + + +### Example + +```ruby +# user.rb +class User + include ActiveModel::SerializerSupport + + attributes :first_name, :last_name, :email +end +``` + +```ruby +# user_serializer.rb +class UserSerializer < ActiveModel::Serializer + attributes :first_name, :last_name +end +``` + + +## Rspec + +See "Writing Tests" in https://github.com/intridea/grape. + +Enjoy :) + +## Contributing + +1. Fork it +2. Create your feature branch (`git checkout -b my-new-feature`) +3. Commit your changes (`git commit -am 'Added some feature'`) +4. Push to the branch (`git push origin my-new-feature`) +5. Create new Pull Request + + +## Thanks to + +The developers and maintainers of: +[active_model_serializers](https://github.com/rails-api/active_model_serializers) +[Grape](https://github.com/intridea/grape)! + +Structured and based upon [Grape](https://github.com/LTe/grape-rabl). diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..da5d3ba --- /dev/null +++ b/Rakefile @@ -0,0 +1,11 @@ +#!/usr/bin/env rake +require "bundler/gem_tasks" + +require 'rspec/core' +require 'rspec/core/rake_task' +RSpec::Core::RakeTask.new(:spec) do |spec| + spec.rspec_opts = ['-fd -c'] + spec.pattern = FileList['spec/**/*_spec.rb'] +end + +task :default => :spec \ No newline at end of file diff --git a/grape-active_model_serializers.gemspec b/grape-active_model_serializers.gemspec new file mode 100644 index 0000000..cb6555a --- /dev/null +++ b/grape-active_model_serializers.gemspec @@ -0,0 +1,23 @@ +# -*- encoding: utf-8 -*- +require File.expand_path('../lib/grape-active_model_serializers/version', __FILE__) + +Gem::Specification.new do |gem| + gem.authors = ["Jonathan Richard Henry Evans"] + gem.email = ["contact@jrhe.co.uk"] + gem.description = %q{Use active_model_serializer in grape} + gem.summary = %q{Use active_model_serializer in grape} + gem.homepage = "https://github.com/jrhe/grape-rabl" + + gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } + gem.files = `git ls-files`.split("\n") + gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") + gem.name = "grape-active_model_serializers" + gem.require_paths = ["lib"] + 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" +end diff --git a/lib/.rspec b/lib/.rspec new file mode 100644 index 0000000..d3ad5a9 --- /dev/null +++ b/lib/.rspec @@ -0,0 +1,2 @@ +--color +--format=documentation diff --git a/lib/.travis.yml b/lib/.travis.yml new file mode 100644 index 0000000..1852caf --- /dev/null +++ b/lib/.travis.yml @@ -0,0 +1,8 @@ +rvm: + - 1.9.2 + - 1.9.3 + - ruby-head + - rbx-19mode + +env: + - JRUBY_OPTS="--1.9" \ No newline at end of file diff --git a/lib/grape-active_model_serializers.rb b/lib/grape-active_model_serializers.rb new file mode 100644 index 0000000..f26ef11 --- /dev/null +++ b/lib/grape-active_model_serializers.rb @@ -0,0 +1,5 @@ +require 'active_model_serializers' +require 'grape' +require 'hashie/hash' +require "grape-active_model_serializers/version" +require "grape-active_model_serializers/formatter" \ No newline at end of file diff --git a/lib/grape-active_model_serializers/formatter.rb b/lib/grape-active_model_serializers/formatter.rb new file mode 100644 index 0000000..c36fdbb --- /dev/null +++ b/lib/grape-active_model_serializers/formatter.rb @@ -0,0 +1,50 @@ +require 'active_record' + +module Grape + module Formatter + module ActiveModelSerializers + class << self + + attr_reader :env + attr_reader :endpoint + + def call(object, env) + @object = object + @env = env + @endpoint = env['api.endpoint'] + + 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 + else + Grape::Formatter::Json.call object, env + end + end + + private + def active_model_serializer + _active_model_serializer + end + + def active_model_serializer? + !!active_model_serializer + end + + def _active_model_serializer + route_options = endpoint.options[:route_options] + + # Infer serializer name if its not set + route_options[:serializer] = @object.class.name unless route_options.has_key? :serializer + + 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) + end + serializer + end + end + end + end +end \ No newline at end of file diff --git a/lib/grape-active_model_serializers/version.rb b/lib/grape-active_model_serializers/version.rb new file mode 100644 index 0000000..d434368 --- /dev/null +++ b/lib/grape-active_model_serializers/version.rb @@ -0,0 +1,5 @@ +module Grape + module ActiveModelSerializers + VERSION = "0.1.0" + end +end diff --git a/lib/grape/active_model_serializers.rb b/lib/grape/active_model_serializers.rb new file mode 100644 index 0000000..3d0dcd5 --- /dev/null +++ b/lib/grape/active_model_serializers.rb @@ -0,0 +1 @@ +require 'grape-active_model_serializers' \ No newline at end of file diff --git a/spec/.DS_Store b/spec/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 {'adapter' => 'nulldb'}) + end + + def app + subject + end + + it "should use the built in grape serializer when serializer is set to nil" do + subject.get("/home", serializer: nil) do + {user: {first_name: "JR", last_name: "HE"}} + end + get("/home") + last_response.body.should == "{\"user\":{\"first_name\":\"JR\",\"last_name\":\"HE\"}}" + end + + + it "should respond with proper content-type" do + subject.get("/home", :serializer => "user") do + {user: {first_name: "JR", last_name: "HE"}} + end + get("/home") + last_response.headers["Content-Type"].should == "application/json" + end + + it "should 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=>{: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 + + get "/home" + last_response.body.should == '{:user=>{:first_name=>"JR", :last_name=>"HE"}}' + end + end +end + diff --git a/spec/schema.rb b/spec/schema.rb new file mode 100644 index 0000000..215c183 --- /dev/null +++ b/spec/schema.rb @@ -0,0 +1,10 @@ +ActiveRecord::Schema.define(version: 20130403105356) do + create_table "users", force: true do |t| + t.string "username" + t.string "first_name" + t.string "last_name" + + t.datetime "created_at" + t.datetime "updated_at" + end +end \ No newline at end of file diff --git a/spec/spec_fakes.rb b/spec/spec_fakes.rb new file mode 100644 index 0000000..2661bed --- /dev/null +++ b/spec/spec_fakes.rb @@ -0,0 +1,9 @@ +require 'active_model' + +class User < ActiveRecord::Base + attr_accessor :first_name, :last_name, :password, :email +end + +class UserSerializer < ActiveModel::Serializer + attributes :first_name, :last_name +end \ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..239ae5f --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,29 @@ +$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) +$LOAD_PATH.unshift(File.dirname(__FILE__)) + +require 'bundler' +Bundler.setup :default, :test + +require 'active_support/core_ext/hash/conversions' +require 'active_model' +require "active_model_serializers" +require "active_support/json" +require 'grape/active_model_serializers' +require 'rspec' +require 'rack/test' +require "pry" +require 'nulldb_rspec' + +include NullDB::RSpec::NullifiedDatabase + +NullDB.configure do |ndb| + def ndb.project_root + File.dirname(__FILE__) + end +end + +RSpec.configure do |config| + config.include Rack::Test::Methods +end + +Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}