Skip to content

Instantly share code, notes, and snippets.

@soeffing
Created December 29, 2014 17:20
Show Gist options
  • Save soeffing/bfcb9bdb1867d5b70e1d to your computer and use it in GitHub Desktop.
Save soeffing/bfcb9bdb1867d5b70e1d to your computer and use it in GitHub Desktop.
API
module Api
module V2
class ApiController < ::ApplicationController
before_action :doorkeeper_authorize!, unless: :public_endpoint?
skip_before_filter :verify_authenticity_token
skip_before_filter :ensure_locale_and_platform
skip_before_filter :store_locale_and_platform
skip_before_filter :set_user_time_zone
# JSON API ONLY
respond_to :json
before_filter :parse_params, only: [:index, :show, :me]
def current_resource_owner
User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token && doorkeeper_token.resource_owner_id
end
def parse_params
@api_query = ApiQueryService.new(params)
end
def check_for_file_urls
klass = infer_class_from_current_controller
param_key = infer_param_key_from_current_controller
params[param_key].each do |attribute, value|
# check if attr is a paperclip attachement on given model
if Paperclip::AttachmentRegistry.definitions_for(klass).keys.include?(attribute.to_sym)
# check if value is a valid uri/url
next unless uri?(value)
params[param_key][attribute] = open(value)
end
end
end
# TODO: Refactor this & Add decorator methods
def add_computable_attributes
clazz = infer_class_from_current_controller
Paperclip::AttachmentRegistry.definitions_for(clazz).each do |paperclip_attachment|
styles = []
if paperclip_attachment[1].has_key?(:styles)
paperclip_attachment[1][:styles].each_pair do |name, dimension|
styles.push(name)
end
end
single_attachment = Hash.new
single_attachment[paperclip_attachment[0].to_s] = styles
@return_attributes.push(single_attachment)
end
end
def public_endpoint?
public_endpoints = [
{ controller: 'docs' , action: 'index' }
]
public_endpoints.map{ |endpoint| endpoint[:controller] == controller_name && endpoint[:action] == action_name }.include?(true)
end
# Check whether a string is a valid URI
def uri?(string)
uri = URI.parse(string)
%w( http https ).include?(uri.scheme)
rescue URI::BadURIError
false
rescue URI::InvalidURIError
false
end
# Infer the model class from the controller this methods is called in
def infer_class_from_current_controller
self.class.to_s.match(/V2::(.+)Controller/)[1].singularize.constantize
end
# Infer the model class from the controller this methods is called in
def infer_param_key_from_current_controller
self.class.to_s.match(/V2::(.+)Controller/)[1].singularize.downcase
end
# Resource controller action
def show
@object = infer_class_from_current_controller.find(params[:id])
render json: JsonResponseBuilder.new(@object, @return_attributes, @api_query).render
rescue ActiveRecord::RecordNotFound
render 'api/v2/shared/not_found.json.jbuilder'
end
def update
@object = infer_class_from_current_controller.find(params[:id])
if @object.update_attributes(params[infer_param_key_from_current_controller.to_sym])
render json: JsonResponseBuilder.new(@object, @return_attributes, @api_query).render
else
render 'api/v2/shared/errors.json.jbuilder'
end
end
def create
@object = infer_class_from_current_controller.new(params[infer_param_key_from_current_controller.to_sym])
if @object.save
render json: JsonResponseBuilder.new(@object, @return_attributes, @api_query).render
else
render 'api/v2/shared/errors.json.jbuilder'
end
end
def index
if @api_query.filter && @api_query.order
@collection = infer_class_from_current_controller.where(@api_query.filter).order(@api_query.order)
elsif @api_query.filter
@collection = infer_class_from_current_controller.where(@api_query.filter)
elsif @api_query.order
@collection = infer_class_from_current_controller.order(@api_query.order)
else
@collection = infer_class_from_current_controller.all
end
# the paginate method is from the api-pagination gem and paginates the collection
# and return a @pagination_meta hash
paginate json: @collection
render json: JsonResponseBuilder.new(@collection, @return_attributes, @api_query, @pagination_meta).render_index
end
def destroy
@object = infer_class_from_current_controller.find(params[:id]).destroy
render json: JsonResponseBuilder.new(@object, @return_attributes, @api_query).render
rescue ActiveRecord::RecordNotFound
render 'api/v2/shared/not_found.json.jbuilder'
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment