active_response 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|