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
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "sweet_actions"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/lib/.DS_Store
ADDED
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Rails
|
2
|
+
module Generators
|
3
|
+
class ActionsGenerator < NamedBase
|
4
|
+
source_root File.expand_path('../templates', __FILE__)
|
5
|
+
|
6
|
+
def create_actions_folder
|
7
|
+
template 'collect.rb.erb', File.join('app/actions', plural_name, 'collect.rb')
|
8
|
+
template 'create.rb.erb', File.join('app/actions', plural_name, 'create.rb')
|
9
|
+
template 'destroy.rb.erb', File.join('app/actions', plural_name, 'destroy.rb')
|
10
|
+
template 'show.rb.erb', File.join('app/actions', plural_name, 'show.rb')
|
11
|
+
template 'update.rb.erb', File.join('app/actions', plural_name, 'update.rb')
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def module_name
|
17
|
+
plural_name.classify.pluralize
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
Binary file
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module SweetActions
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path('../templates', __FILE__)
|
5
|
+
|
6
|
+
desc 'Creates a Sweet Actions initializer in your application.'
|
7
|
+
|
8
|
+
def copy_initializer
|
9
|
+
copy_file 'initializer.rb', 'config/initializers/sweet_actions.rb'
|
10
|
+
copy_file 'collect_action.rb', 'app/actions/collect_action.rb'
|
11
|
+
copy_file 'create_action.rb', 'app/actions/create_action.rb'
|
12
|
+
copy_file 'destroy_action.rb', 'app/actions/destroy_action.rb'
|
13
|
+
copy_file 'show_action.rb', 'app/actions/show_action.rb'
|
14
|
+
copy_file 'update_action.rb', 'app/actions/update_action.rb'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class SweetActionsController < ApplicationController
|
2
|
+
include SweetActions::ControllerConcerns
|
3
|
+
end
|
4
|
+
|
5
|
+
SweetActions.config do |config|
|
6
|
+
# REST actions must implement `authorize` method
|
7
|
+
# setting to true is the most secure
|
8
|
+
config.authorize_rest_requests = true
|
9
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module SweetActions
|
2
|
+
class << self
|
3
|
+
def configuration
|
4
|
+
@config ||= SweetActions::Configuration.new
|
5
|
+
end
|
6
|
+
|
7
|
+
def config
|
8
|
+
yield configuration
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
ActiveSupport.run_load_hooks(:sweet_actions, self)
|
13
|
+
end
|
14
|
+
|
15
|
+
# overhead
|
16
|
+
require 'sweet_actions/version'
|
17
|
+
require 'sweet_actions/configuration'
|
18
|
+
require 'sweet_actions/exceptions'
|
19
|
+
|
20
|
+
# base classes
|
21
|
+
require 'sweet_actions/action_factory'
|
22
|
+
require 'sweet_actions/api_action'
|
23
|
+
|
24
|
+
# concerns
|
25
|
+
require 'sweet_actions/rest_serializer_concerns'
|
26
|
+
require 'sweet_actions/rest_concerns'
|
27
|
+
require 'sweet_actions/authorization_concerns'
|
28
|
+
require 'sweet_actions/save_concerns'
|
29
|
+
require 'sweet_actions/read_concerns'
|
30
|
+
|
31
|
+
# actions
|
32
|
+
require 'sweet_actions/collect_action'
|
33
|
+
require 'sweet_actions/create_action'
|
34
|
+
require 'sweet_actions/update_action'
|
35
|
+
require 'sweet_actions/show_action'
|
36
|
+
require 'sweet_actions/destroy_action'
|
37
|
+
|
38
|
+
# helpers
|
39
|
+
require 'sweet_actions/controller_concerns'
|
40
|
+
require 'sweet_actions/routes_helpers'
|
41
|
+
|
42
|
+
require 'sweet_actions/railtie' if defined?(::Rails)
|
Binary file
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module SweetActions
|
2
|
+
class ActionFactory
|
3
|
+
attr_reader :controller, :resource_name, :action, :namespace
|
4
|
+
|
5
|
+
def initialize(controller, action_name)
|
6
|
+
@controller = controller
|
7
|
+
path_parameters = env['action_dispatch.request.path_parameters']
|
8
|
+
@resource_name = path_parameters[:resource_name]
|
9
|
+
@action = action_name
|
10
|
+
@namespace = path_parameters[:namespace]
|
11
|
+
end
|
12
|
+
|
13
|
+
def build_action
|
14
|
+
action_class.new(controller)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def env
|
20
|
+
controller.request.env
|
21
|
+
end
|
22
|
+
|
23
|
+
def action_class
|
24
|
+
klass_name = [namespace, resource_module, action_class_name].compact.join('::')
|
25
|
+
return klass_name.constantize if klass_defined?(klass_name)
|
26
|
+
default_action
|
27
|
+
end
|
28
|
+
|
29
|
+
def resource_module
|
30
|
+
return nil unless resource_name
|
31
|
+
resource_name.pluralize
|
32
|
+
end
|
33
|
+
|
34
|
+
def action_class_name
|
35
|
+
raise 'action is required to be passed into actionFactory' unless action.present?
|
36
|
+
action.to_s.classify
|
37
|
+
end
|
38
|
+
|
39
|
+
def default_action
|
40
|
+
modules = namespace.split('::')
|
41
|
+
class_found = false
|
42
|
+
klass_name = nil
|
43
|
+
|
44
|
+
until class_found || modules.count == 0
|
45
|
+
namespace_to_test = modules.join('::')
|
46
|
+
target = "#{namespace_to_test}::Defaults::#{action_class_name}"
|
47
|
+
if klass_defined?(target)
|
48
|
+
klass_name = target
|
49
|
+
class_found = true
|
50
|
+
end
|
51
|
+
modules.pop
|
52
|
+
end
|
53
|
+
return klass_name.constantize if klass_name.present?
|
54
|
+
"#{action_class_name}Action".constantize
|
55
|
+
end
|
56
|
+
|
57
|
+
def klass_defined?(klass_name)
|
58
|
+
klass_name.constantize
|
59
|
+
return true
|
60
|
+
rescue
|
61
|
+
return false
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module SweetActions
|
2
|
+
class ApiAction
|
3
|
+
attr_reader :controller, :response_data, :response_code
|
4
|
+
|
5
|
+
def initialize(controller, options = {})
|
6
|
+
@controller = controller
|
7
|
+
after_init(options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def perform_action
|
11
|
+
run_action = Proc.new do
|
12
|
+
@response_data = action
|
13
|
+
end
|
14
|
+
|
15
|
+
debug_mode? ? run_action.call : fail_gracefully(run_action)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def after_init(options); end
|
21
|
+
|
22
|
+
def fail_gracefully(proc)
|
23
|
+
@response_code = '200'
|
24
|
+
begin
|
25
|
+
proc.call
|
26
|
+
rescue Exceptions::NotAuthorized => e
|
27
|
+
@response_code = '401'
|
28
|
+
@response_data = {
|
29
|
+
message: 'not authorized'
|
30
|
+
}
|
31
|
+
rescue StandardError => e
|
32
|
+
@response_code = '500'
|
33
|
+
@response_data = {
|
34
|
+
server_error: e.message
|
35
|
+
}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def debug_mode?
|
40
|
+
ENV['SWEET_ACTION_DEBUG_MODE'] == true
|
41
|
+
end
|
42
|
+
|
43
|
+
def action
|
44
|
+
raise "action method is required for #{self.class.name} because it inherits from ApiAction"
|
45
|
+
end
|
46
|
+
|
47
|
+
def path_parameters
|
48
|
+
@path_parameters ||= env['action_dispatch.request.path_parameters']
|
49
|
+
end
|
50
|
+
|
51
|
+
def request
|
52
|
+
@request ||= controller.request
|
53
|
+
end
|
54
|
+
|
55
|
+
def params
|
56
|
+
@params ||= controller.params
|
57
|
+
end
|
58
|
+
|
59
|
+
def env
|
60
|
+
request.env
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module SweetActions
|
2
|
+
module AuthorizationConcerns
|
3
|
+
private
|
4
|
+
|
5
|
+
def authorize?
|
6
|
+
SweetActions.configuration.authorize_rest_requests
|
7
|
+
end
|
8
|
+
|
9
|
+
def authorize
|
10
|
+
return unless authorize?
|
11
|
+
return true if authorized?
|
12
|
+
unauthorized
|
13
|
+
end
|
14
|
+
|
15
|
+
def authorized?
|
16
|
+
raise "authorized? method is required for the #{self.class.name} action"
|
17
|
+
end
|
18
|
+
|
19
|
+
def unauthorized
|
20
|
+
raise Exceptions::NotAuthorized
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|