sweet_actions 0.1.4
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/.gitignore +12 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/PITCHME.md +224 -0
- data/PITCHME.yaml +1 -0
- data/README.md +257 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/.DS_Store +0 -0
- data/lib/generators/.DS_Store +0 -0
- data/lib/generators/rails/.DS_Store +0 -0
- data/lib/generators/rails/actions_generator.rb +21 -0
- data/lib/generators/rails/resource_override.rb +10 -0
- data/lib/generators/rails/templates/.DS_Store +0 -0
- data/lib/generators/rails/templates/collect.rb.erb +11 -0
- data/lib/generators/rails/templates/create.rb.erb +15 -0
- data/lib/generators/rails/templates/destroy.rb.erb +15 -0
- data/lib/generators/rails/templates/show.rb.erb +11 -0
- data/lib/generators/rails/templates/update.rb.erb +11 -0
- data/lib/generators/sweet_actions/install_generator.rb +18 -0
- data/lib/generators/sweet_actions/templates/collect_action.rb +10 -0
- data/lib/generators/sweet_actions/templates/create_action.rb +14 -0
- data/lib/generators/sweet_actions/templates/destroy_action.rb +14 -0
- data/lib/generators/sweet_actions/templates/initializer.rb +9 -0
- data/lib/generators/sweet_actions/templates/show_action.rb +10 -0
- data/lib/generators/sweet_actions/templates/update_action.rb +10 -0
- data/lib/sweet_actions.rb +42 -0
- data/lib/sweet_actions/.DS_Store +0 -0
- data/lib/sweet_actions/action_factory.rb +64 -0
- data/lib/sweet_actions/api_action.rb +63 -0
- data/lib/sweet_actions/authorization_concerns.rb +23 -0
- data/lib/sweet_actions/collect_action.rb +11 -0
- data/lib/sweet_actions/configuration.rb +9 -0
- data/lib/sweet_actions/controller_concerns.rb +10 -0
- data/lib/sweet_actions/create_action.rb +6 -0
- data/lib/sweet_actions/destroy_action.rb +19 -0
- data/lib/sweet_actions/exceptions.rb +5 -0
- data/lib/sweet_actions/railtie.rb +8 -0
- data/lib/sweet_actions/read_concerns.rb +14 -0
- data/lib/sweet_actions/rest_concerns.rb +47 -0
- data/lib/sweet_actions/rest_serializer_concerns.rb +54 -0
- data/lib/sweet_actions/routes_helpers.rb +40 -0
- data/lib/sweet_actions/save_concerns.rb +51 -0
- data/lib/sweet_actions/show_action.rb +9 -0
- data/lib/sweet_actions/update_action.rb +6 -0
- data/lib/sweet_actions/version.rb +3 -0
- data/sweet_actions-0.1.0.gem +0 -0
- data/sweet_actions.gemspec +36 -0
- metadata +139 -0
@@ -0,0 +1,10 @@
|
|
1
|
+
module SweetActions
|
2
|
+
module ControllerConcerns
|
3
|
+
def action_missing(action_name)
|
4
|
+
factory = ActionFactory.new(self, action_name)
|
5
|
+
action = factory.build_action
|
6
|
+
action.perform_action
|
7
|
+
render status: action.response_code, json: action.response_data
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module SweetActions
|
2
|
+
class DestroyAction < ApiAction
|
3
|
+
include RestConcerns
|
4
|
+
include AuthorizationConcerns
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def action
|
9
|
+
@resource = set_resource
|
10
|
+
authorize
|
11
|
+
destroy
|
12
|
+
serialize
|
13
|
+
end
|
14
|
+
|
15
|
+
def destroy
|
16
|
+
raise "destroy method must be implemented in #{self.class.name} class since it inherits from DestroyAction"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module SweetActions
|
2
|
+
module RestConcerns
|
3
|
+
include RestSerializerConcerns
|
4
|
+
|
5
|
+
attr_reader :resource_name, :resource
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def resource_name
|
10
|
+
path_parameters[:resource_name]
|
11
|
+
end
|
12
|
+
|
13
|
+
def set_resource
|
14
|
+
raise "set_resource method must be implemented in #{self.class.name} class since it includes RestConcerns"
|
15
|
+
end
|
16
|
+
|
17
|
+
def resource
|
18
|
+
return @resource if defined?("@resource")
|
19
|
+
raise "@resource must be set for #{self.class.name} since it includes RestConcerns"
|
20
|
+
end
|
21
|
+
|
22
|
+
def resource_class
|
23
|
+
resource_name.constantize
|
24
|
+
end
|
25
|
+
|
26
|
+
def resource_decanter
|
27
|
+
decanter_class_name = "#{resource_class.to_s.classify}Decanter"
|
28
|
+
begin
|
29
|
+
decanter_class_name.constantize
|
30
|
+
rescue
|
31
|
+
raise "The following Decanter was not found: #{decanter_class_name} and is required for create and update actions"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def resource_params
|
36
|
+
@resource_params ||= resource_decanter.decant(params[singular_key])
|
37
|
+
end
|
38
|
+
|
39
|
+
def plural_key
|
40
|
+
resource_class.name.underscore.pluralize
|
41
|
+
end
|
42
|
+
|
43
|
+
def singular_key
|
44
|
+
resource_class.name.underscore
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module SweetActions
|
2
|
+
module RestSerializerConcerns
|
3
|
+
private
|
4
|
+
|
5
|
+
def root_key
|
6
|
+
raise "root_key method must be implemented in #{self.class.name} since it includes RestSerializerConcerns"
|
7
|
+
end
|
8
|
+
|
9
|
+
def serialize
|
10
|
+
return serialize_destroyed_resource if destroyed?
|
11
|
+
|
12
|
+
{
|
13
|
+
type: root_key,
|
14
|
+
attributes: serialized_attributes
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def serialize_destroyed_resource
|
19
|
+
{ root_key => {} }
|
20
|
+
end
|
21
|
+
|
22
|
+
def serialize_errors
|
23
|
+
{
|
24
|
+
errors: {
|
25
|
+
singular_key => map_base_to__error(errors.messages)
|
26
|
+
}
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
def errors
|
31
|
+
resource.respond_to?(:errors) && resource.errors
|
32
|
+
end
|
33
|
+
|
34
|
+
def serialized_attributes
|
35
|
+
return resource unless serialized_resource
|
36
|
+
serialized_resource.serializer_instance
|
37
|
+
end
|
38
|
+
|
39
|
+
def serialized_resource
|
40
|
+
return nil unless Object.const_defined?('ActiveModelSerializers')
|
41
|
+
@serialized_resource ||= begin
|
42
|
+
ActiveModelSerializers::SerializableResource.new(resource, serializer_options)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def serializer_options
|
47
|
+
{}
|
48
|
+
end
|
49
|
+
|
50
|
+
def destroyed?
|
51
|
+
resource.respond_to?(:destroyed?) && resource.destroyed?
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
def create_sweet_action(method, path, action, options = {})
|
2
|
+
to = options.fetch(:to, "sweet_actions##{action}")
|
3
|
+
|
4
|
+
valid_methods = %i[get post put delete]
|
5
|
+
raise 'not a valid method' unless valid_methods.include?(method.to_sym)
|
6
|
+
args = { to: to }.merge(options)
|
7
|
+
send(method, path, args)
|
8
|
+
end
|
9
|
+
|
10
|
+
def create_sweet_actions(resource, options = {})
|
11
|
+
path = options.fetch(:path, '/')
|
12
|
+
namespace = options.fetch(:namespace, nil)
|
13
|
+
singular = resource.to_s.singularize
|
14
|
+
resource_class = singular.classify
|
15
|
+
actions = %i[collect show create update destroy]
|
16
|
+
only = options.fetch(:only, actions)
|
17
|
+
base_path = "#{path}#{resource}"
|
18
|
+
|
19
|
+
options = options.merge(resource_name: resource_class, namespace: namespace)
|
20
|
+
|
21
|
+
if only.include?(:collect) || only.include?(:index)
|
22
|
+
create_sweet_action(:get, base_path, :collect, options)
|
23
|
+
end
|
24
|
+
|
25
|
+
if only.include?(:show)
|
26
|
+
create_sweet_action(:get, "#{base_path}/:id", :show, options)
|
27
|
+
end
|
28
|
+
|
29
|
+
if only.include?(:create)
|
30
|
+
create_sweet_action(:post, base_path, :create, options)
|
31
|
+
end
|
32
|
+
|
33
|
+
if only.include?(:update)
|
34
|
+
create_sweet_action(:put, "#{base_path}/:id", :update, options)
|
35
|
+
end
|
36
|
+
|
37
|
+
if only.include?(:destroy)
|
38
|
+
create_sweet_action(:delete, "#{base_path}/:id", :destroy, options)
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module SweetActions
|
2
|
+
module SaveConcerns
|
3
|
+
include AuthorizationConcerns
|
4
|
+
|
5
|
+
def action
|
6
|
+
@resource = set_resource
|
7
|
+
authorize
|
8
|
+
validate_and_save ? success : failure
|
9
|
+
end
|
10
|
+
|
11
|
+
def root_key
|
12
|
+
singular_key
|
13
|
+
end
|
14
|
+
|
15
|
+
def validate_and_save
|
16
|
+
valid? && save
|
17
|
+
end
|
18
|
+
|
19
|
+
def valid?
|
20
|
+
true
|
21
|
+
end
|
22
|
+
|
23
|
+
def save
|
24
|
+
raise "save method must be implemented by #{self.class.name} since it includes SaveConcerns"
|
25
|
+
end
|
26
|
+
|
27
|
+
def success
|
28
|
+
after_save
|
29
|
+
serialize
|
30
|
+
end
|
31
|
+
|
32
|
+
def failure
|
33
|
+
after_fail
|
34
|
+
@response_code = '422'
|
35
|
+
serialize_errors
|
36
|
+
end
|
37
|
+
|
38
|
+
def after_save
|
39
|
+
# hook
|
40
|
+
end
|
41
|
+
|
42
|
+
def after_fail
|
43
|
+
# hook
|
44
|
+
end
|
45
|
+
|
46
|
+
def map_base_to__error(error_obj)
|
47
|
+
error_obj[:_error] = error_obj.delete(:base) if error_obj.key? :base
|
48
|
+
error_obj
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
Binary file
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'sweet_actions/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "sweet_actions"
|
8
|
+
spec.version = SweetActions::VERSION
|
9
|
+
spec.authors = ["Ryan Francis"]
|
10
|
+
spec.email = ["ryan@launchpadlab.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{A more object oriented approach to controller actions}
|
13
|
+
spec.description = %q{Each controller action is its own class, making it possible to abstract tasks like authorization, deserialization, serialization, and callbacks.}
|
14
|
+
spec.homepage = "https://github.com/launchpadlab/sweet_actions"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
18
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
19
|
+
if spec.respond_to?(:metadata)
|
20
|
+
spec.metadata['allowed_push_host'] = "https://rubygems.org"
|
21
|
+
else
|
22
|
+
raise "RubyGems 2.0 or newer is required to protect against " \
|
23
|
+
"public gem pushes."
|
24
|
+
end
|
25
|
+
|
26
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
27
|
+
f.match(%r{^(test|spec|features)/})
|
28
|
+
end
|
29
|
+
spec.bindir = "exe"
|
30
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
31
|
+
spec.require_paths = ["lib"]
|
32
|
+
|
33
|
+
spec.add_development_dependency "bundler", "~> 1.14"
|
34
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
35
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
36
|
+
end
|
metadata
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sweet_actions
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ryan Francis
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-08-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.14'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.14'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
description: Each controller action is its own class, making it possible to abstract
|
56
|
+
tasks like authorization, deserialization, serialization, and callbacks.
|
57
|
+
email:
|
58
|
+
- ryan@launchpadlab.com
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- ".gitignore"
|
64
|
+
- ".rspec"
|
65
|
+
- ".travis.yml"
|
66
|
+
- Gemfile
|
67
|
+
- LICENSE.txt
|
68
|
+
- PITCHME.md
|
69
|
+
- PITCHME.yaml
|
70
|
+
- README.md
|
71
|
+
- Rakefile
|
72
|
+
- bin/console
|
73
|
+
- bin/setup
|
74
|
+
- lib/.DS_Store
|
75
|
+
- lib/generators/.DS_Store
|
76
|
+
- lib/generators/rails/.DS_Store
|
77
|
+
- lib/generators/rails/actions_generator.rb
|
78
|
+
- lib/generators/rails/resource_override.rb
|
79
|
+
- lib/generators/rails/templates/.DS_Store
|
80
|
+
- lib/generators/rails/templates/collect.rb.erb
|
81
|
+
- lib/generators/rails/templates/create.rb.erb
|
82
|
+
- lib/generators/rails/templates/destroy.rb.erb
|
83
|
+
- lib/generators/rails/templates/show.rb.erb
|
84
|
+
- lib/generators/rails/templates/update.rb.erb
|
85
|
+
- lib/generators/sweet_actions/install_generator.rb
|
86
|
+
- lib/generators/sweet_actions/templates/collect_action.rb
|
87
|
+
- lib/generators/sweet_actions/templates/create_action.rb
|
88
|
+
- lib/generators/sweet_actions/templates/destroy_action.rb
|
89
|
+
- lib/generators/sweet_actions/templates/initializer.rb
|
90
|
+
- lib/generators/sweet_actions/templates/show_action.rb
|
91
|
+
- lib/generators/sweet_actions/templates/update_action.rb
|
92
|
+
- lib/sweet_actions.rb
|
93
|
+
- lib/sweet_actions/.DS_Store
|
94
|
+
- lib/sweet_actions/action_factory.rb
|
95
|
+
- lib/sweet_actions/api_action.rb
|
96
|
+
- lib/sweet_actions/authorization_concerns.rb
|
97
|
+
- lib/sweet_actions/collect_action.rb
|
98
|
+
- lib/sweet_actions/configuration.rb
|
99
|
+
- lib/sweet_actions/controller_concerns.rb
|
100
|
+
- lib/sweet_actions/create_action.rb
|
101
|
+
- lib/sweet_actions/destroy_action.rb
|
102
|
+
- lib/sweet_actions/exceptions.rb
|
103
|
+
- lib/sweet_actions/railtie.rb
|
104
|
+
- lib/sweet_actions/read_concerns.rb
|
105
|
+
- lib/sweet_actions/rest_concerns.rb
|
106
|
+
- lib/sweet_actions/rest_serializer_concerns.rb
|
107
|
+
- lib/sweet_actions/routes_helpers.rb
|
108
|
+
- lib/sweet_actions/save_concerns.rb
|
109
|
+
- lib/sweet_actions/show_action.rb
|
110
|
+
- lib/sweet_actions/update_action.rb
|
111
|
+
- lib/sweet_actions/version.rb
|
112
|
+
- sweet_actions-0.1.0.gem
|
113
|
+
- sweet_actions.gemspec
|
114
|
+
homepage: https://github.com/launchpadlab/sweet_actions
|
115
|
+
licenses:
|
116
|
+
- MIT
|
117
|
+
metadata:
|
118
|
+
allowed_push_host: https://rubygems.org
|
119
|
+
post_install_message:
|
120
|
+
rdoc_options: []
|
121
|
+
require_paths:
|
122
|
+
- lib
|
123
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
requirements: []
|
134
|
+
rubyforge_project:
|
135
|
+
rubygems_version: 2.6.13
|
136
|
+
signing_key:
|
137
|
+
specification_version: 4
|
138
|
+
summary: A more object oriented approach to controller actions
|
139
|
+
test_files: []
|