active_response 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/active_response.rb +23 -0
- data/lib/active_response/controller.rb +19 -0
- data/lib/active_response/controller/core.rb +94 -0
- data/lib/active_response/controller/crud_defaults.rb +62 -0
- data/lib/active_response/controller/crud_defaults/create.rb +47 -0
- data/lib/active_response/controller/crud_defaults/destroy.rb +41 -0
- data/lib/active_response/controller/crud_defaults/edit.rb +19 -0
- data/lib/active_response/controller/crud_defaults/index.rb +37 -0
- data/lib/active_response/controller/crud_defaults/new.rb +19 -0
- data/lib/active_response/controller/crud_defaults/show.rb +31 -0
- data/lib/active_response/controller/crud_defaults/update.rb +41 -0
- data/lib/active_response/controller/default_responses.rb +39 -0
- data/lib/active_response/controller/resource_helper.rb +44 -0
- data/lib/active_response/railtie.rb +12 -0
- data/lib/active_response/responders/base.rb +38 -0
- data/lib/active_response/responders/html.rb +54 -0
- data/lib/active_response/responders/js.rb +13 -0
- data/lib/active_response/responders/json.rb +42 -0
- data/lib/active_response/responders/json_api.rb +53 -0
- data/lib/active_response/version.rb +5 -0
- metadata +127 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 84258f703a2b8a0d27572d8c88b7680900a8839dc75d142cba9dd1a10e996069
|
4
|
+
data.tar.gz: d37a387ec872cdc12d4902fc2d895aea56848a41072820f54e77c66eb045f249
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 58f65299722bf90c02023e7774a3830ca59ec3452b9b837ad24dc0a43f20d591bdbea893e3aac43ed8416bc8065332ea388dd064c0ddda536eab347c80083d36
|
7
|
+
data.tar.gz: 648800aa8e5b1079a6e0822a24ef7c6a5a84adabe2e6430a82d0e6bd160374fcb4c8626861f8a14a68b435d00777d2a528b6340ee95afe1b535fcebd709d2f0f
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_response/controller'
|
4
|
+
require 'active_response/responders/base'
|
5
|
+
require 'active_response/railtie' if defined?(Rails::Railtie)
|
6
|
+
|
7
|
+
module ActiveResponse
|
8
|
+
cattr_accessor :responders
|
9
|
+
self.responders = {}
|
10
|
+
|
11
|
+
def self.responder_for(format)
|
12
|
+
responders[format] ||=
|
13
|
+
registered_responders
|
14
|
+
.sort_by { |d| -d.ancestors.count }
|
15
|
+
.detect { |responder| responder.formats.include?(format) }
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.registered_responders
|
19
|
+
return @registered_responders if @registered_responders.present?
|
20
|
+
Dir[Rails.root.join('app', 'responders', '*.rb')].each { |file| require_dependency file }
|
21
|
+
@registered_responders = ActiveResponse::Responders::Base.descendants
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_response/controller/core'
|
4
|
+
require 'active_response/controller/crud_defaults'
|
5
|
+
require 'active_response/controller/default_responses'
|
6
|
+
require 'active_response/controller/resource_helper'
|
7
|
+
|
8
|
+
module ActiveResponse
|
9
|
+
module Controller
|
10
|
+
extend ActiveSupport::Concern
|
11
|
+
|
12
|
+
included do
|
13
|
+
include Controller::Core
|
14
|
+
include Controller::CrudDefaults
|
15
|
+
include Controller::DefaultResponses
|
16
|
+
include Controller::ResourceHelper
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveResponse
|
4
|
+
module Controller
|
5
|
+
module Core
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
attr_reader :active_responder
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
def active_response(*actions)
|
14
|
+
active_response(:create, :destroy, :edit, :index, :new, :show, :update) if actions.include?(:crud)
|
15
|
+
actions.without(:crud).each { |action| define_active_response_action(action) }
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def define_active_response_action(action)
|
21
|
+
define_method action do
|
22
|
+
active_response_block do
|
23
|
+
execute_action
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def active_response_block
|
32
|
+
respond_to do |format|
|
33
|
+
ActiveResponse::Responders::Base.available_formats.each do |symbol|
|
34
|
+
format.send(symbol) do
|
35
|
+
find_active_responder(format)
|
36
|
+
yield
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def active_response_type
|
43
|
+
@active_responder.type
|
44
|
+
end
|
45
|
+
|
46
|
+
def active_response_options
|
47
|
+
base = "#{action_name}_#{@active_response_resolution}_options"
|
48
|
+
if respond_to?("#{base}_#{active_response_type}", true)
|
49
|
+
send("#{base}_#{active_response_type}")
|
50
|
+
else
|
51
|
+
send(base)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def active_response_handle_failure(_resource = nil)
|
56
|
+
respond_with_failure!
|
57
|
+
if respond_to?("#{action_name}_failure_#{active_response_type}", true)
|
58
|
+
return send("#{action_name}_failure_#{active_response_type}")
|
59
|
+
end
|
60
|
+
send("#{action_name}_failure")
|
61
|
+
end
|
62
|
+
|
63
|
+
def active_response_handle_success(_resource = nil)
|
64
|
+
respond_with_success!
|
65
|
+
if respond_to?("#{action_name}_success_#{active_response_type}", true)
|
66
|
+
return send("#{action_name}_success_#{active_response_type}")
|
67
|
+
end
|
68
|
+
send("#{action_name}_success")
|
69
|
+
end
|
70
|
+
|
71
|
+
def active_response_success?
|
72
|
+
@active_response_resolution == :success
|
73
|
+
end
|
74
|
+
|
75
|
+
def execute_action
|
76
|
+
return active_response_handle_success unless respond_to?("#{action_name}_execute", true)
|
77
|
+
send("#{action_name}_execute") ? active_response_handle_success : active_response_handle_failure
|
78
|
+
end
|
79
|
+
|
80
|
+
def find_active_responder(format)
|
81
|
+
format_symbol = format.format.symbol
|
82
|
+
@active_responder = ActiveResponse.responder_for(format_symbol).new(self, format_symbol)
|
83
|
+
end
|
84
|
+
|
85
|
+
def respond_with_failure!
|
86
|
+
@active_response_resolution = :failure
|
87
|
+
end
|
88
|
+
|
89
|
+
def respond_with_success!
|
90
|
+
@active_response_resolution = :success
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_response/controller/crud_defaults/create'
|
4
|
+
require 'active_response/controller/crud_defaults/destroy'
|
5
|
+
require 'active_response/controller/crud_defaults/edit'
|
6
|
+
require 'active_response/controller/crud_defaults/index'
|
7
|
+
require 'active_response/controller/crud_defaults/new'
|
8
|
+
require 'active_response/controller/crud_defaults/show'
|
9
|
+
require 'active_response/controller/crud_defaults/update'
|
10
|
+
|
11
|
+
module ActiveResponse
|
12
|
+
module Controller
|
13
|
+
module CrudDefaults
|
14
|
+
include Create
|
15
|
+
include Destroy
|
16
|
+
include Edit
|
17
|
+
include Index
|
18
|
+
include New
|
19
|
+
include Show
|
20
|
+
include Update
|
21
|
+
|
22
|
+
def default_form_options(action)
|
23
|
+
{
|
24
|
+
locals: form_view_locals_for(action),
|
25
|
+
resource: current_resource,
|
26
|
+
view: form_view_for(action)
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
def form_view_for(action)
|
31
|
+
return send("#{action}_view") if respond_to?("#{action}_view", true)
|
32
|
+
default_form_view(action)
|
33
|
+
end
|
34
|
+
|
35
|
+
def default_form_view(action)
|
36
|
+
action
|
37
|
+
end
|
38
|
+
|
39
|
+
def form_view_locals_for(action)
|
40
|
+
return send("#{action}_view_locals") if respond_to?("#{action}_view_locals", true)
|
41
|
+
default_form_view_locals(action)
|
42
|
+
end
|
43
|
+
|
44
|
+
def default_form_view_locals(_action)
|
45
|
+
{}
|
46
|
+
end
|
47
|
+
|
48
|
+
def active_response_success_message
|
49
|
+
return send("#{action_name}_success_message") if respond_to?("#{action_name}_success_message", true)
|
50
|
+
I18n.t(success_message_translation_key, success_message_translation_opts)
|
51
|
+
end
|
52
|
+
|
53
|
+
def success_message_translation_key
|
54
|
+
"active_response.actions.#{action_name}.success"
|
55
|
+
end
|
56
|
+
|
57
|
+
def success_message_translation_opts
|
58
|
+
{type: current_resource.class.to_s.humanize}
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveResponse
|
4
|
+
module Controller
|
5
|
+
module CrudDefaults
|
6
|
+
module Create
|
7
|
+
private
|
8
|
+
|
9
|
+
def create_execute
|
10
|
+
current_resource.assign_attributes(permit_params)
|
11
|
+
current_resource.save
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_failure
|
15
|
+
respond_with_invalid_resource(active_response_options)
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_failure_options
|
19
|
+
{
|
20
|
+
resource: current_resource
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
def create_includes
|
25
|
+
{}
|
26
|
+
end
|
27
|
+
|
28
|
+
def create_success
|
29
|
+
respond_with_new_resource(active_response_options)
|
30
|
+
end
|
31
|
+
|
32
|
+
def create_success_options
|
33
|
+
{
|
34
|
+
include: create_includes,
|
35
|
+
location: create_success_location,
|
36
|
+
notice: active_response_success_message,
|
37
|
+
resource: current_resource
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
def create_success_location
|
42
|
+
url_for(current_resource)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveResponse
|
4
|
+
module Controller
|
5
|
+
module CrudDefaults
|
6
|
+
module Destroy
|
7
|
+
private
|
8
|
+
|
9
|
+
def destroy_execute
|
10
|
+
current_resource.destroy
|
11
|
+
end
|
12
|
+
|
13
|
+
def destroy_failure
|
14
|
+
respond_with_invalid_resource(active_response_options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def destroy_failure_options
|
18
|
+
{
|
19
|
+
resource: current_resource
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def destroy_success
|
24
|
+
respond_with_destroyed(active_response_options)
|
25
|
+
end
|
26
|
+
|
27
|
+
def destroy_success_options
|
28
|
+
{
|
29
|
+
location: destroy_success_location,
|
30
|
+
notice: active_response_success_message,
|
31
|
+
resource: current_resource
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def destroy_success_location
|
36
|
+
url_for("/#{controller_name}")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveResponse
|
4
|
+
module Controller
|
5
|
+
module CrudDefaults
|
6
|
+
module Edit
|
7
|
+
private
|
8
|
+
|
9
|
+
def edit_success
|
10
|
+
respond_with_form(active_response_options)
|
11
|
+
end
|
12
|
+
|
13
|
+
def edit_success_options
|
14
|
+
default_form_options(:edit)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveResponse
|
4
|
+
module Controller
|
5
|
+
module CrudDefaults
|
6
|
+
module Index
|
7
|
+
private
|
8
|
+
|
9
|
+
def index_association
|
10
|
+
var = :"@#{controller_name}"
|
11
|
+
return instance_variable_get(var) if instance_variable_defined?(var)
|
12
|
+
instance_variable_set(:"@#{controller_name}", controller_class.all)
|
13
|
+
end
|
14
|
+
|
15
|
+
def index_success
|
16
|
+
respond_with_collection(active_response_options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def index_success_options
|
20
|
+
{
|
21
|
+
collection: index_association,
|
22
|
+
include: index_includes,
|
23
|
+
locals: index_locals
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def index_locals
|
28
|
+
{}
|
29
|
+
end
|
30
|
+
|
31
|
+
def index_includes
|
32
|
+
{}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveResponse
|
4
|
+
module Controller
|
5
|
+
module CrudDefaults
|
6
|
+
module New
|
7
|
+
private
|
8
|
+
|
9
|
+
def new_success
|
10
|
+
respond_with_form(active_response_options)
|
11
|
+
end
|
12
|
+
|
13
|
+
def new_success_options
|
14
|
+
default_form_options(:new)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveResponse
|
4
|
+
module Controller
|
5
|
+
module CrudDefaults
|
6
|
+
module Show
|
7
|
+
private
|
8
|
+
|
9
|
+
def show_success
|
10
|
+
respond_with_resource(active_response_options)
|
11
|
+
end
|
12
|
+
|
13
|
+
def show_success_options
|
14
|
+
{
|
15
|
+
include: show_includes,
|
16
|
+
locals: show_view_locals,
|
17
|
+
resource: current_resource
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
def show_includes
|
22
|
+
{}
|
23
|
+
end
|
24
|
+
|
25
|
+
def show_view_locals
|
26
|
+
{}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveResponse
|
4
|
+
module Controller
|
5
|
+
module CrudDefaults
|
6
|
+
module Update
|
7
|
+
private
|
8
|
+
|
9
|
+
def update_execute
|
10
|
+
current_resource.update permit_params
|
11
|
+
end
|
12
|
+
|
13
|
+
def update_failure
|
14
|
+
respond_with_invalid_resource(active_response_options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def update_failure_options
|
18
|
+
{
|
19
|
+
resource: current_resource
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def update_success
|
24
|
+
respond_with_updated_resource(active_response_options)
|
25
|
+
end
|
26
|
+
|
27
|
+
def update_success_options
|
28
|
+
{
|
29
|
+
location: update_success_location,
|
30
|
+
notice: active_response_success_message,
|
31
|
+
resource: current_resource
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def update_success_location
|
36
|
+
url_for(current_resource)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveResponse
|
4
|
+
module Controller
|
5
|
+
module DefaultResponses
|
6
|
+
def respond_with_collection(opts)
|
7
|
+
active_responder.collection(opts)
|
8
|
+
end
|
9
|
+
|
10
|
+
def respond_with_destroyed(opts)
|
11
|
+
active_responder.destroyed(opts)
|
12
|
+
end
|
13
|
+
|
14
|
+
def respond_with_form(opts)
|
15
|
+
active_responder.form(opts)
|
16
|
+
end
|
17
|
+
|
18
|
+
def respond_with_invalid_resource(opts)
|
19
|
+
active_responder.invalid_resource(opts)
|
20
|
+
end
|
21
|
+
|
22
|
+
def respond_with_new_resource(opts)
|
23
|
+
active_responder.new_resource(opts)
|
24
|
+
end
|
25
|
+
|
26
|
+
def respond_with_redirect(opts)
|
27
|
+
active_responder.redirect(opts)
|
28
|
+
end
|
29
|
+
|
30
|
+
def respond_with_resource(opts)
|
31
|
+
active_responder.resource(opts)
|
32
|
+
end
|
33
|
+
|
34
|
+
def respond_with_updated_resource(opts)
|
35
|
+
active_responder.updated_resource(opts)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveResponse
|
4
|
+
module Controller
|
5
|
+
module ResourceHelper
|
6
|
+
private
|
7
|
+
|
8
|
+
def current_resource
|
9
|
+
var = :"@#{controller_name.singularize}"
|
10
|
+
return instance_variable_get(var) if instance_variable_defined?(var)
|
11
|
+
instance_variable_set(var, resolve_current_resource)
|
12
|
+
end
|
13
|
+
|
14
|
+
def controller_class
|
15
|
+
@controller_class ||= controller_name.classify.safe_constantize
|
16
|
+
end
|
17
|
+
|
18
|
+
def requested_resource
|
19
|
+
@requested_resource ||= controller_class.find_by(id: resource_id)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Instantiates a new record of the current controller type
|
23
|
+
# @return [ActiveRecord::Base] A fresh model instance
|
24
|
+
def new_resource
|
25
|
+
controller_class.new
|
26
|
+
end
|
27
|
+
|
28
|
+
def resolve_current_resource
|
29
|
+
case action_name
|
30
|
+
when 'create', 'new'
|
31
|
+
new_resource
|
32
|
+
when 'index'
|
33
|
+
nil
|
34
|
+
else
|
35
|
+
requested_resource
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def resource_id
|
40
|
+
params[:id]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveResponse
|
4
|
+
class Railtie < ::Rails::Railtie
|
5
|
+
initializer 'active_response.insert_middleware' do |_app|
|
6
|
+
ActiveSupport::Reloader.to_prepare do
|
7
|
+
ActiveResponse.responders = {}
|
8
|
+
ActiveResponse.instance_variable_set(:@registered_responders, nil)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveResponse
|
4
|
+
module Responders
|
5
|
+
class Base
|
6
|
+
attr_accessor :controller
|
7
|
+
attr_accessor :format
|
8
|
+
|
9
|
+
class_attribute :formats
|
10
|
+
self.formats = []
|
11
|
+
|
12
|
+
def initialize(controller, format)
|
13
|
+
self.controller = controller
|
14
|
+
self.format = format
|
15
|
+
end
|
16
|
+
|
17
|
+
def type
|
18
|
+
self.class.type
|
19
|
+
end
|
20
|
+
|
21
|
+
class << self
|
22
|
+
def respond_to(*formats)
|
23
|
+
self.formats = formats
|
24
|
+
end
|
25
|
+
|
26
|
+
def type
|
27
|
+
@type ||= name.gsub('Responder', '').underscore.to_sym
|
28
|
+
end
|
29
|
+
|
30
|
+
def available_formats
|
31
|
+
return @available_formats if @available_formats.present?
|
32
|
+
@available_formats =
|
33
|
+
ActiveResponse.registered_responders.map(&:formats).flatten.sort { |format| format == :html ? 0 : 1 }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_response/responders/base'
|
4
|
+
|
5
|
+
module ActiveResponse
|
6
|
+
module Responders
|
7
|
+
class HTML < Base
|
8
|
+
def collection(**opts)
|
9
|
+
controller.render opts
|
10
|
+
end
|
11
|
+
|
12
|
+
def destroyed(**opts)
|
13
|
+
opts[:status] = 303
|
14
|
+
controller.respond_with_redirect(opts)
|
15
|
+
end
|
16
|
+
|
17
|
+
def form(**opts)
|
18
|
+
controller.render opts[:view], opts.except(:view)
|
19
|
+
end
|
20
|
+
|
21
|
+
def invalid_resource(**opts)
|
22
|
+
if controller.action_name == 'destroy'
|
23
|
+
controller.respond_with_redirect(location: opts[:resource])
|
24
|
+
else
|
25
|
+
controller.respond_with_form(controller.default_form_options(form_for_invalid(opts)))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def new_resource(**opts)
|
30
|
+
controller.respond_with_redirect(opts)
|
31
|
+
end
|
32
|
+
|
33
|
+
def redirect(**opts)
|
34
|
+
controller.send(:redirect_to, opts[:location], opts.except(:location))
|
35
|
+
end
|
36
|
+
|
37
|
+
def resource(**opts)
|
38
|
+
controller.render :show, opts
|
39
|
+
end
|
40
|
+
|
41
|
+
def updated_resource(**opts)
|
42
|
+
controller.respond_with_redirect(opts)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def form_for_invalid(opts)
|
48
|
+
return opts[:form] if opts[:form].present?
|
49
|
+
return 'new' if controller.action_name == 'create'
|
50
|
+
'edit'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_response/responders/html'
|
4
|
+
|
5
|
+
module ActiveResponse
|
6
|
+
module Responders
|
7
|
+
class JS < HTML
|
8
|
+
def redirect(**opts)
|
9
|
+
controller.render js: "window.location = '#{opts[:location]}'"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_response/responders/html'
|
4
|
+
|
5
|
+
module ActiveResponse
|
6
|
+
module Responders
|
7
|
+
class JSON < HTML
|
8
|
+
def collection(**opts)
|
9
|
+
opts[:json] = opts.delete(:collection)
|
10
|
+
controller.render opts
|
11
|
+
end
|
12
|
+
|
13
|
+
def destroyed(_opts)
|
14
|
+
controller.head :no_content
|
15
|
+
end
|
16
|
+
|
17
|
+
def form(**_opts)
|
18
|
+
raise NotImplementedError, 'Forms are not available in JSON'
|
19
|
+
end
|
20
|
+
|
21
|
+
def invalid_resource(**opts)
|
22
|
+
opts[:json] = opts.delete(:resource).errors
|
23
|
+
opts[:status] ||= :unprocessable_entity
|
24
|
+
controller.render opts
|
25
|
+
end
|
26
|
+
|
27
|
+
def new_resource(**opts)
|
28
|
+
opts[:status] = :created
|
29
|
+
controller.respond_with_resource(opts)
|
30
|
+
end
|
31
|
+
|
32
|
+
def resource(**opts)
|
33
|
+
opts[:json] = opts.delete(:resource)
|
34
|
+
controller.render opts
|
35
|
+
end
|
36
|
+
|
37
|
+
def updated_resource(**opts)
|
38
|
+
controller.respond_with_resource(opts)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_response/responders/json'
|
4
|
+
|
5
|
+
module ActiveResponse
|
6
|
+
module Responders
|
7
|
+
class JsonApi < JSON
|
8
|
+
def collection(**opts)
|
9
|
+
opts[:adapter] = :json_api
|
10
|
+
super
|
11
|
+
end
|
12
|
+
|
13
|
+
def invalid_resource(**opts)
|
14
|
+
controller.render json: {errors: formatted_errors(opts[:resource].errors)}, status: :unprocessable_entity
|
15
|
+
end
|
16
|
+
|
17
|
+
def resource(**opts)
|
18
|
+
opts[:adapter] = :json_api
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def error_code(errors, key, index)
|
25
|
+
"value_#{errors.details[key][index][:error]}".upcase
|
26
|
+
end
|
27
|
+
|
28
|
+
def formatted_error(errors, key)
|
29
|
+
errors.full_messages_for(key).map.with_index { |m, i| formatted_error_hash(key, error_code(errors, key, i), m) }
|
30
|
+
end
|
31
|
+
|
32
|
+
def formatted_error_hash(key, code, message)
|
33
|
+
{
|
34
|
+
code: code,
|
35
|
+
message: message,
|
36
|
+
status: Rack::Utils::HTTP_STATUS_CODES[422],
|
37
|
+
source: {parameter: key}
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
def formatted_errors(errors)
|
42
|
+
case errors
|
43
|
+
when Array
|
44
|
+
errors.map { |error| formatted_errors(error) }.flatten
|
45
|
+
when ActiveModel::Errors
|
46
|
+
errors.keys.reduce([]) do |array, key|
|
47
|
+
array.concat(formatted_error(errors, key))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
metadata
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: active_response
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Arthur Dingemans
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-07-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: active_model_serializers
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.10'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.10'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: railties
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 4.2.0
|
34
|
+
- - "<"
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '6'
|
37
|
+
type: :runtime
|
38
|
+
prerelease: false
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 4.2.0
|
44
|
+
- - "<"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '6'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rspec-rails
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - '='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 3.7.2
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - '='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 3.7.2
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: rubocop
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - '='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 0.58.2
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - '='
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 0.58.2
|
75
|
+
description: DRY your controllers and make your API more predictable by defining responders
|
76
|
+
for different formats. E.g. Posting an invalid resource in HTML should render a
|
77
|
+
form with errors, while in JSON you expect serialized errors.
|
78
|
+
email:
|
79
|
+
- arthur@argu.co
|
80
|
+
executables: []
|
81
|
+
extensions: []
|
82
|
+
extra_rdoc_files: []
|
83
|
+
files:
|
84
|
+
- lib/active_response.rb
|
85
|
+
- lib/active_response/controller.rb
|
86
|
+
- lib/active_response/controller/core.rb
|
87
|
+
- lib/active_response/controller/crud_defaults.rb
|
88
|
+
- lib/active_response/controller/crud_defaults/create.rb
|
89
|
+
- lib/active_response/controller/crud_defaults/destroy.rb
|
90
|
+
- lib/active_response/controller/crud_defaults/edit.rb
|
91
|
+
- lib/active_response/controller/crud_defaults/index.rb
|
92
|
+
- lib/active_response/controller/crud_defaults/new.rb
|
93
|
+
- lib/active_response/controller/crud_defaults/show.rb
|
94
|
+
- lib/active_response/controller/crud_defaults/update.rb
|
95
|
+
- lib/active_response/controller/default_responses.rb
|
96
|
+
- lib/active_response/controller/resource_helper.rb
|
97
|
+
- lib/active_response/railtie.rb
|
98
|
+
- lib/active_response/responders/base.rb
|
99
|
+
- lib/active_response/responders/html.rb
|
100
|
+
- lib/active_response/responders/js.rb
|
101
|
+
- lib/active_response/responders/json.rb
|
102
|
+
- lib/active_response/responders/json_api.rb
|
103
|
+
- lib/active_response/version.rb
|
104
|
+
homepage: https://github.com/ontola/active_response
|
105
|
+
licenses:
|
106
|
+
- MIT
|
107
|
+
metadata: {}
|
108
|
+
post_install_message:
|
109
|
+
rdoc_options: []
|
110
|
+
require_paths:
|
111
|
+
- lib
|
112
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - ">="
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
requirements: []
|
123
|
+
rubygems_version: 3.0.1
|
124
|
+
signing_key:
|
125
|
+
specification_version: 4
|
126
|
+
summary: Define Responders to handle different kind of responses in different formats
|
127
|
+
test_files: []
|