1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
|
module ActsAsApi
# This module enriches the ActiveRecord::Base module of Rails.
module Base
# Indicates if the current model acts as api.
# False by default.
def acts_as_api?
false
end
# When invoked, it enriches the current model with the
# class and instance methods to act as api.
def acts_as_api
class_eval do
include ActsAsApi::Base::InstanceMethods
extend ActsAsApi::Base::ClassMethods
end
if block_given?
yield ActsAsApi::Config
end
end
module ClassMethods
def acts_as_api? #:nodoc:
included_modules.include?(InstanceMethods)
end
# Determines the attributes, methods of the model that are accessible in the api response.
# *Note*: There is only whitelisting for api accessible attributes.
# So once the model acts as api, you have to determine all attributes here that should
# be contained in the api responses.
def api_accessible(api_template, options = {}, &block)
attributes = api_accessible_attributes(api_template).try(:dup) || ApiTemplate.new(api_template)
attributes.merge!(api_accessible_attributes(options[:extend])) if options[:extend]
if block_given?
yield attributes
end
class_attribute "api_accessible_#{api_template}".to_sym
send "api_accessible_#{api_template}=", attributes
end
# Returns an array of all the attributes that have been made accessible to the api response.
def api_accessible_attributes(api_template)
begin send "api_accessible_#{api_template}".to_sym rescue nil end
end
end
module InstanceMethods
# Creates the api response of the model and returns it as a Hash.
# Will raise an exception if the passed api template is not defined for the model
def as_api_response(api_template, options = {})
api_attributes = self.class.api_accessible_attributes(api_template)
raise ActsAsApi::TemplateNotFoundError.new("acts_as_api template :#{api_template} was not found for model #{self.class}") if api_attributes.nil?
before_api_response(api_template)
response_hash = around_api_response(api_template) do
api_attributes.to_response_hash(self, api_attributes, options)
end
after_api_response(api_template)
response_hash
end
protected
def before_api_response(_api_template)
end
def after_api_response(_api_template)
end
def around_api_response(_api_template)
yield
end
end
end
end
|