require "make_restful/version" module MakeRestful extend ActiveSupport::Concern extend ActiveSupport::Autoload autoload :ClassMethods autoload :ControllerAdditions included do cattr_accessor :allowed_methods, :allowed_formats, :finder, :pagination, :resource_class resource name.underscore.gsub(/(.*)_controller/,'\1').singularize allow_formats :json, :jsonp, :xml allow_methods :index, :get, :put, :post, :delete find_by :id #################################### ## RESTful Methods #################################### end # GET /resources def index head :method_not_allowed and return unless allow_method? :index, :list @response = { :"#{self.class.resource_name}" => @collection } @response.merge!( { current_page: results.current_page, per_page: results.per_page, total_entries: results.total_entries, } ) if self.class.pagination && !params.has_key?(:all) if @collection.empty? @response = { error: 'no results found' } @status = :not_found end render_formats end # POST /resources def create head :method_not_allowed and return unless allow_method? :post, :create @response = @resource.create render_formats end # PUT /resources/:id def show head :method_not_allowed and return unless allow_method? :get, :show @response = @instance unless @response @response = { error: 'record_not_found' } @status = :not_found end render_formats end # PUT /resources/:id def update head :method_not_allowed and return unless allow_method? :put, :patch, :update @response = @instance.update_attributes(params[@resource.to_s.underscore]) render_formats end # DELETE /resources/:id def destroy head :method_not_allowed and return unless allow_method? :delete, :destroy @response = @instance.destroy render_formats end # OPTIONS /resources def spec @response = { supports: self.class.supported_methods, specification: ( @resource.specification if @resource.respond_to?(:specification) ) || "No Specification" } render_formats end private ## Rendering def render_formats respond_to do |format| format.json { render json: @response, status: @status, callback: ( params[:callback] if allow_format? :jsonp )} if allow_format? :json, :jsonp format.xml { render xml: @response, status: @status } if allow_format? :xml format.html { render status: @status } if allow_format? :html end end # Is a format allowed? def allow_format?(*formats) true if formats.map(&:to_sym).select { |i| allowed_formats.map(&:to_sym).include? i }.present? end # Is a method allowed? def allow_method?(*methods) true if methods.map(&:to_sym).select { |i| allowed_methods.map(&:to_sym).include? i }.present? end def load_resource @resource = self.class.resource_class @resource.params = params.except(:action, :controller, :id) if @resource.respond_to?(:params=) end def load_collection @collection = if self.class.pagination && !params.has_key?(:all) @resource.paginate page: params[:page], per_page: (params[:per_page] || self.class.pagination[:per_page] || 25) else @resource.all end eval("@#{self.class.resource_name} = @collection") end def load_instance @instance = eval "@#{self.class.instance_name} = #{@resource.send(:"find_by_#{self.class.finder}", params[:id])}" if params[:id] && @resource.respond_to?(:find) end def resource @resource end def instance @instance end def collection @collection end end