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.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +21 -0
  7. data/PITCHME.md +224 -0
  8. data/PITCHME.yaml +1 -0
  9. data/README.md +257 -0
  10. data/Rakefile +6 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/lib/.DS_Store +0 -0
  14. data/lib/generators/.DS_Store +0 -0
  15. data/lib/generators/rails/.DS_Store +0 -0
  16. data/lib/generators/rails/actions_generator.rb +21 -0
  17. data/lib/generators/rails/resource_override.rb +10 -0
  18. data/lib/generators/rails/templates/.DS_Store +0 -0
  19. data/lib/generators/rails/templates/collect.rb.erb +11 -0
  20. data/lib/generators/rails/templates/create.rb.erb +15 -0
  21. data/lib/generators/rails/templates/destroy.rb.erb +15 -0
  22. data/lib/generators/rails/templates/show.rb.erb +11 -0
  23. data/lib/generators/rails/templates/update.rb.erb +11 -0
  24. data/lib/generators/sweet_actions/install_generator.rb +18 -0
  25. data/lib/generators/sweet_actions/templates/collect_action.rb +10 -0
  26. data/lib/generators/sweet_actions/templates/create_action.rb +14 -0
  27. data/lib/generators/sweet_actions/templates/destroy_action.rb +14 -0
  28. data/lib/generators/sweet_actions/templates/initializer.rb +9 -0
  29. data/lib/generators/sweet_actions/templates/show_action.rb +10 -0
  30. data/lib/generators/sweet_actions/templates/update_action.rb +10 -0
  31. data/lib/sweet_actions.rb +42 -0
  32. data/lib/sweet_actions/.DS_Store +0 -0
  33. data/lib/sweet_actions/action_factory.rb +64 -0
  34. data/lib/sweet_actions/api_action.rb +63 -0
  35. data/lib/sweet_actions/authorization_concerns.rb +23 -0
  36. data/lib/sweet_actions/collect_action.rb +11 -0
  37. data/lib/sweet_actions/configuration.rb +9 -0
  38. data/lib/sweet_actions/controller_concerns.rb +10 -0
  39. data/lib/sweet_actions/create_action.rb +6 -0
  40. data/lib/sweet_actions/destroy_action.rb +19 -0
  41. data/lib/sweet_actions/exceptions.rb +5 -0
  42. data/lib/sweet_actions/railtie.rb +8 -0
  43. data/lib/sweet_actions/read_concerns.rb +14 -0
  44. data/lib/sweet_actions/rest_concerns.rb +47 -0
  45. data/lib/sweet_actions/rest_serializer_concerns.rb +54 -0
  46. data/lib/sweet_actions/routes_helpers.rb +40 -0
  47. data/lib/sweet_actions/save_concerns.rb +51 -0
  48. data/lib/sweet_actions/show_action.rb +9 -0
  49. data/lib/sweet_actions/update_action.rb +6 -0
  50. data/lib/sweet_actions/version.rb +3 -0
  51. data/sweet_actions-0.1.0.gem +0 -0
  52. data/sweet_actions.gemspec +36 -0
  53. metadata +139 -0
@@ -0,0 +1,9 @@
1
+ module SweetActions
2
+ class Configuration
3
+ attr_accessor :authorize_rest_requests
4
+
5
+ def initialize
6
+ @authorize_rest_requests = true
7
+ end
8
+ end
9
+ end
@@ -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,6 @@
1
+ module SweetActions
2
+ class CreateAction < ApiAction
3
+ include RestConcerns
4
+ include SaveConcerns
5
+ end
6
+ 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,5 @@
1
+ module SweetActions
2
+ module Exceptions
3
+ class NotAuthorized < StandardError; end
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ # require 'sweet_actions'
2
+
3
+ # class SweetActions::Railtie < Rails::Railtie
4
+ # generators do |app|
5
+ # Rails::Generators.configure!(app.config.generators)
6
+ # Rails::Generators.hidden_namespaces.uniq!
7
+ # end
8
+ # end
@@ -0,0 +1,14 @@
1
+ module SweetActions
2
+ module ReadConcerns
3
+ include RestConcerns
4
+ include AuthorizationConcerns
5
+
6
+ private
7
+
8
+ def action
9
+ @resource = set_resource
10
+ authorize
11
+ serialize
12
+ end
13
+ end
14
+ 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
@@ -0,0 +1,9 @@
1
+ module SweetActions
2
+ class ShowAction < ApiAction
3
+ include ReadConcerns
4
+
5
+ def root_key
6
+ singular_key
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ module SweetActions
2
+ class UpdateAction < ApiAction
3
+ include RestConcerns
4
+ include SaveConcerns
5
+ end
6
+ end
@@ -0,0 +1,3 @@
1
+ module SweetActions
2
+ VERSION = "0.1.4"
3
+ 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: []