Class: Rails::ResourceService

Inherits:
Object
  • Object
show all
Defined in:
lib/rails/resource_service.rb

Overview

ResourceService supports index/show/create/update/destroy REST API calls for any Rails resources Automatically loads the authenticity token from meta content attribute Assumes a resource or resource class that matches the name of a Backend ActiveRecord Model (e.g. Contact class or instance)

Constant Summary collapse

TIMESTAMP_ATTRIBUTES =
['created_at', 'updated_at']

Class Method Summary collapse

Class Method Details

.authenticity_tokenObject



113
114
115
# File 'lib/rails/resource_service.rb', line 113

def authenticity_token
  Element['meta[name=csrf-token]'].attr('content')
end

.build_resource_from_response_object(resource_class:, resource_response_object:) ⇒ Object



122
123
124
125
126
# File 'lib/rails/resource_service.rb', line 122

def build_resource_from_response_object(resource_class:, resource_response_object:)
  resource = resource_class.new
  resource_response_object.each { |attribute, value| resource.send("#{attribute}=", value) rescue nil }
  resource
end

.create(resource: nil, resource_class: nil, resource_attributes: nil, singular_resource_name: nil, plural_resource_name: nil, create_resource_url: nil, params: nil, &response_handler) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/rails/resource_service.rb', line 54

def create(resource: nil, resource_class: nil, resource_attributes: nil, singular_resource_name: nil, plural_resource_name: nil, create_resource_url: nil, params: nil, &response_handler)
  resource_class ||= resource&.class
  singular_resource_name ||= singular_resource_name_for_resource_class(resource_class)
  plural_resource_name ||= "#{singular_resource_name}s"
  create_resource_url ||= "/#{plural_resource_name}.json"
  HTTP.post(create_resource_url, payload: create_update_resource_params(resource:, resource_class:, resource_attributes:, singular_resource_name:, params: params.to_h)) do |response|
    if response.ok?
      if !resource_class.nil?
        resource_response_object = Native(response.body)
        resource = build_resource_from_response_object(resource_class:, resource_response_object:)
      end
    else
      errors = JSON.parse(response.body)
    end
    response_handler.call(response, resource, errors)
  end
end

.create_update_resource_params(resource: nil, resource_class: nil, resource_attributes: nil, singular_resource_name: nil, params: nil) ⇒ Object



103
104
105
106
107
108
109
110
111
# File 'lib/rails/resource_service.rb', line 103

def create_update_resource_params(resource: nil, resource_class: nil, resource_attributes: nil, singular_resource_name: nil, params: nil)
  resource_class ||= resource&.class
  singular_resource_name ||= singular_resource_name_for_resource_class(resource_class)
  resource_params = {authenticity_token:}
  resource_attributes ||= resource&.to_h&.reject { |attribute, value| TIMESTAMP_ATTRIBUTES.include?(attribute) }
  resource_params[singular_resource_name] = resource_attributes.to_h
  resource_params = resource_params.merge(params.to_h)
  resource_params
end

.destroy(resource: nil, resource_class: nil, resource_id: nil, singular_resource_name: nil, plural_resource_name: nil, destroy_resource_url: nil, params: nil, &response_handler) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
# File 'lib/rails/resource_service.rb', line 91

def destroy(resource: nil, resource_class: nil, resource_id: nil, singular_resource_name: nil, plural_resource_name: nil, destroy_resource_url: nil, params: nil, &response_handler)
  resource_class ||= resource&.class
  resource_id ||= resource&.id
  singular_resource_name ||= singular_resource_name_for_resource_class(resource_class)
  plural_resource_name ||= "#{singular_resource_name}s"
  destroy_resource_url ||= "/#{plural_resource_name}/#{resource_id}.json"
  path_url = destroy_resource_url.start_with?('/')
  destroy_resource_url = Glimmer::Util::UrlBuilder.new.url(destroy_resource_url).params({authenticity_token:}.merge(params.to_h)).to_s
  destroy_resource_url = destroy_resource_url.sub('https://', '') if path_url
  HTTP.delete(destroy_resource_url, &response_handler)
end

.index(resource: nil, resource_class: nil, singular_resource_name: nil, plural_resource_name: nil, index_resource_url: nil, params: nil, root: nil, &response_handler) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/rails/resource_service.rb', line 12

def index(resource: nil, resource_class: nil, singular_resource_name: nil, plural_resource_name: nil, index_resource_url: nil, params: nil, root: nil, &response_handler)
  resource_class ||= resource&.class
  singular_resource_name ||= singular_resource_name_for_resource_class(resource_class)
  plural_resource_name ||= "#{singular_resource_name}s"
  index_resource_url ||= "/#{plural_resource_name}.json"
  root = plural_resource_name if root == true
  path_url = index_resource_url.start_with?('/')
  index_resource_url = Glimmer::Util::UrlBuilder.new.url(index_resource_url).params(params.to_h).to_s
  index_resource_url = index_resource_url.sub('https://', '') if path_url
  HTTP.get(index_resource_url) do |response|
    if response.ok? && !resource_class.nil?
      resource_response_objects = Native(response.body)
       = {}
      if root
        resources = resource_response_objects[root].map { |resource_response_object| build_resource_from_response_object(resource_class:, resource_response_object:) }
        (metadata:, native_response: resource_response_objects, root:)
      else
        resources = resource_response_objects.map { |resource_response_object| build_resource_from_response_object(resource_class:, resource_response_object:) }
      end
    end
    response_handler.call(response, resources, ) # TODO support 3rd argument for metadata
  end
end

.populate_metadata_from_native_response(metadata:, native_response:, root:) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/rails/resource_service.rb', line 128

def (metadata:, native_response:, root:)
  native_response.each do |attribute, value|
    next if attribute == root
    begin
      value.class
      [attribute] = value
    rescue Exception => e
      if `typeof #{value}` == 'object'
        [attribute] = {}
        (metadata: [attribute], native_response: Native(value), root: nil)
      else
        [attribute] = value
      end
    end
  end
end

.show(resource: nil, resource_class: nil, resource_id: nil, singular_resource_name: nil, plural_resource_name: nil, show_resource_url: nil, params: nil, &response_handler) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/rails/resource_service.rb', line 36

def show(resource: nil, resource_class: nil, resource_id: nil, singular_resource_name: nil, plural_resource_name: nil, show_resource_url: nil, params: nil, &response_handler)
  resource_class ||= resource&.class
  resource_id ||= resource&.id
  singular_resource_name ||= singular_resource_name_for_resource_class(resource_class)
  plural_resource_name ||= "#{singular_resource_name}s"
  show_resource_url ||= "/#{plural_resource_name}/#{resource_id}.json"
  path_url = show_resource_url.start_with?('/')
  show_resource_url = Glimmer::Util::UrlBuilder.new.url(show_resource_url).params(params.to_h).to_s
  show_resource_url = show_resource_url.sub('https://', '') if path_url
  HTTP.get(show_resource_url) do |response|
    if response.ok? && !resource_class.nil?
      resource_response_object = Native(response.body)
      resource = build_resource_from_response_object(resource_class:, resource_response_object:)
    end
    response_handler.call(response, resource)
  end
end

.singular_resource_name_for_resource_class(resource_class) ⇒ Object



117
118
119
120
# File 'lib/rails/resource_service.rb', line 117

def singular_resource_name_for_resource_class(resource_class)
  return nil if resource_class.nil?
  resource_class.to_s.split('::').last.underscore
end

.update(resource: nil, resource_class: nil, resource_id: nil, resource_attributes: nil, singular_resource_name: nil, plural_resource_name: nil, update_resource_url: nil, params: nil, &response_handler) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/rails/resource_service.rb', line 72

def update(resource: nil, resource_class: nil, resource_id: nil, resource_attributes: nil, singular_resource_name: nil, plural_resource_name: nil, update_resource_url: nil, params: nil, &response_handler)
  resource_class ||= resource&.class
  resource_id ||= resource&.id
  singular_resource_name ||= singular_resource_name_for_resource_class(resource_class)
  plural_resource_name ||= "#{singular_resource_name}s"
  update_resource_url ||= "/#{plural_resource_name}/#{resource_id}.json"
  HTTP.patch(update_resource_url, payload: create_update_resource_params(resource:, resource_class:, resource_attributes:, singular_resource_name:, params: params.to_h)) do |response|
    if response.ok?
      if !resource_class.nil?
        resource_response_object = Native(response.body)
        resource = build_resource_from_response_object(resource_class:, resource_response_object:)
      end
    else
      errors = JSON.parse(response.body)
    end
    response_handler.call(response, resource, errors)
  end
end