sweet_actions 0.1.4

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