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



98
99
100
# File 'lib/rails/resource_service.rb', line 98

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

.build_resource_from_response_object(resource_class:, resource_response_object:) ⇒ Object



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

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



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

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



88
89
90
91
92
93
94
95
96
# File 'lib/rails/resource_service.rb', line 88

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



75
76
77
78
79
80
81
82
# File 'lib/rails/resource_service.rb', line 75

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"
  HTTP.delete(destroy_resource_url, payload: index_show_destroy_resource_params(params: params.to_h), &response_handler)
end

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



9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/rails/resource_service.rb', line 9

def index(resource: nil, resource_class: nil, singular_resource_name: nil, plural_resource_name: nil, index_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"
  index_resource_url ||= "/#{plural_resource_name}.json"
  HTTP.get(index_resource_url, payload: index_show_destroy_resource_params(params: params.to_h)) do |response|
    if response.ok? && !resource_class.nil?
      resource_response_objects = Native(response.body)
      resources = resource_response_objects.map { |resource_response_object| build_resource_from_response_object(resource_class:, resource_response_object:) }
    end
    response_handler.call(response, resources)
  end
end

.index_show_destroy_resource_params(params: nil) ⇒ Object



84
85
86
# File 'lib/rails/resource_service.rb', line 84

def index_show_destroy_resource_params(params: nil)
  {authenticity_token:}.merge(params.to_h)
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



23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/rails/resource_service.rb', line 23

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"
  HTTP.get(show_resource_url, payload: index_show_destroy_resource_params(params: params.to_h)) 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



102
103
104
105
# File 'lib/rails/resource_service.rb', line 102

def singular_resource_name_for_resource_class(resource_class)
  return nil if resource_class.nil?
  resource_class.to_s.split('::').last.downcase
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



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

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