File: base.rb

package info (click to toggle)
ruby-acts-as-api 1.0.1-2.1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, sid, trixie
  • size: 624 kB
  • sloc: ruby: 2,366; makefile: 2
file content (79 lines) | stat: -rw-r--r-- 2,622 bytes parent folder | download | duplicates (2)
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