Skip to content

Instantly share code, notes, and snippets.

@taylor
Forked from mepatterson/gist:5702783
Created June 11, 2013 21:11
Show Gist options
  • Save taylor/5760740 to your computer and use it in GitHub Desktop.
Save taylor/5760740 to your computer and use it in GitHub Desktop.
# ====== TODAY'S KATA:
# * create an Achievements API
# * create an Achievement model, a User model, and a db table for many-many relationship between the two
# * now, write the Goliath+Grape code to create 3 endpoints:
# * 1. an endpoint to SHOW an Achievement (GET /v1/achievements/1)
# * 2. an endpoint to SHOW a User (GET /v1/users/1)
# * 3. an endpoint to GRANT an Achievement to a user (???)
# EXAMPLE GEMFILE THAT SHOULD WORK:
gem 'rack-fiber_pool'
gem 'mysql2'
gem 'activerecord'
gem 'em-synchrony'
gem 'em-http-request'
gem 'grape'
gem 'goliath'
gem 'multi_json'
gem 'oj'
gem 'rabl'
gem 'standalone_migrations'
gem 'rake'
gem 'rspec'
gem 'pry'
gem 'rb-readline'
# in case you need it...
# /config/application.rb
require 'em-synchrony/activerecord'
require 'yaml'
# ---- SETUP THE DATABASE CONNECTION
db = YAML.load(File.open('config/database.yml'))[Goliath.env.to_s]
puts "Establishing db connection: #{db.inspect}"
ActiveRecord::Base.establish_connection(db)
# app.rb
require 'rubygems'
require 'bundler/setup'
require 'goliath'
require 'em-synchrony/activerecord'
require 'grape'
Dir["./app/models/*.rb"].each { |f| require f }
require './app/api'
class Application < Goliath::API
def response(env)
::API.call(env)
end
end
# app/api.rb
Dir["./app/apis/v1/*.rb"].each { |f| require f }
class API < Grape::API
helpers do
def custom_render(rabl_template, object, status, args={})
args[:format] ||= 'json'
args[:success] ||= true
render_options = { format: args[:format] }
render_options[:locals] = args[:locals] if args[:locals]
data = Rabl::Renderer.new(rabl_template, object, render_options).render
%({ "success": #{args[:success]}, "data": #{data} })
end
end
mount APIv1::Unlocks
resource 'servicehealth' do
desc "Returns a basic status report."
get "/" do
MultiJson.dump({
status: 'OK',
environment: Goliath::env })
end
end
end
# app/apis/v1/unlocks.rb
class APIv1
class Unlocks < Grape::API
version 'v1', using: :path, format: :json
resource :unlocks do
# GET /unlocks/1.json
desc "Returns a single Unlock record by ID"
get "/:id" do
unlock = Unlock.find(params[:id])
custom_render "api_v1/unlocks/show", unlock, 200
end
end
end
end
# app/views/api_v1/unlocks/show.json.rabl
attributes :id, :name, :code, :description, :created_at
node(:unique_tags) { |unlock| unlock.tags.uniq }
child :images => :images do
attributes :id, :caption, :mime_type, :url
end
# app/models/unlock.rb
require 'rocket_tag'
class Unlock < ActiveRecord::Base
has_many :images, as: :image_attachable, dependent: :destroy
attr_taggable :tags
validates :name, presence: true
validates :code, presence: true
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment