action-hero 0.1.0
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 +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +162 -0
- data/Rakefile +1 -0
- data/action-hero.gemspec +25 -0
- data/lib/action-hero.rb +1 -0
- data/lib/action_hero.rb +25 -0
- data/lib/action_hero/action.rb +50 -0
- data/lib/action_hero/action_resolver.rb +38 -0
- data/lib/action_hero/configuration.rb +15 -0
- data/lib/action_hero/controller.rb +68 -0
- data/lib/action_hero/log_subscriber.rb +12 -0
- data/lib/action_hero/version.rb +5 -0
- data/lib/dispatcher_ext.rb +47 -0
- metadata +101 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 33c72992fb39f78faad1dfd830fdb08727163293
|
4
|
+
data.tar.gz: deab7549b395659d3517c827be52c74b542f60e6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 58d2b25fffb2ecad60810d066b69ca362d5b8ccd189baabe5773ce17bba06dea9fd10c2888d73c0bc47e9772772834bf4c3e97bbb261e4d4ba8edfe6d402483b
|
7
|
+
data.tar.gz: fe08fc4bc67513626538a34c699d9abdf755ab7ec249dfb88836d82096fdff78e354f6f368fd2f6d673e0bbaba6643b9464757384458dd2f99a4baf0736a70fb
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Jason Harrelson
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
# ActionHero
|
2
|
+
|
3
|
+
Move actions from methods in Rails controllers to action classes.
|
4
|
+
|
5
|
+
|
6
|
+
## Motiviation
|
7
|
+
|
8
|
+
Simple Rails controllers implementing all of the REST actions get crowded enough with at least seven methods. Add any
|
9
|
+
helper methods, etc and things get much worse. In addition, the spec file is even more crowded. All of these concerns
|
10
|
+
jammed into a single class provide many opportunities for bugs. Why should you risk breaking your already implemented and
|
11
|
+
tested index action just because you are adding a show action?
|
12
|
+
|
13
|
+
Finally, controller specs are painfully slow. When ActionHero is used to implement your actions as classes you can achieve
|
14
|
+
full coverage without writing a single controller spec.
|
15
|
+
|
16
|
+
|
17
|
+
## Installation
|
18
|
+
|
19
|
+
Add this line to your application's Gemfile:
|
20
|
+
|
21
|
+
gem 'action-hero'
|
22
|
+
|
23
|
+
And then execute:
|
24
|
+
|
25
|
+
$ bundle
|
26
|
+
|
27
|
+
Or install it yourself as:
|
28
|
+
|
29
|
+
$ gem install action-hero
|
30
|
+
|
31
|
+
|
32
|
+
## Usage
|
33
|
+
|
34
|
+
### Simplest Case
|
35
|
+
|
36
|
+
Include the ActionHero::Controller module in a controller.
|
37
|
+
|
38
|
+
# app/controllers/things_controller.rb
|
39
|
+
class ThingsController < ApplicationController
|
40
|
+
include ActionHero::Controller
|
41
|
+
end
|
42
|
+
|
43
|
+
Define the action class.
|
44
|
+
|
45
|
+
# app/actions/things/index.rb
|
46
|
+
module Things
|
47
|
+
class Index
|
48
|
+
include ActionHero::Action
|
49
|
+
|
50
|
+
def call
|
51
|
+
expose :things, Thing.all
|
52
|
+
respond_with @things
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
Use the exposed object in the view.
|
59
|
+
|
60
|
+
<%= things.each do |thing| %>
|
61
|
+
...
|
62
|
+
<% end %>
|
63
|
+
|
64
|
+
### Exposure
|
65
|
+
|
66
|
+
Unlike controller instance variables, the instance variables set in the action class will not automatically be available
|
67
|
+
in the view. This is just as well, as blindly making all instance variables in the controller available to the view is
|
68
|
+
arguably a bad idea. In order to solve this problem, ActionHero provides the #expose method.
|
69
|
+
|
70
|
+
The expose method does the following:
|
71
|
+
|
72
|
+
* Sets an instance variable in the action class with the same name as provided in the first argument to expose
|
73
|
+
* Returns the value passed in the second parameter so that you can set a local variable
|
74
|
+
* Stores the value in a data store held on the controller
|
75
|
+
* Implements a helper method on the controller to access the exposed value
|
76
|
+
* Makes the helper method available in the view
|
77
|
+
|
78
|
+
Example of usage:
|
79
|
+
|
80
|
+
# in the action class
|
81
|
+
count = expose( :count, 1 )
|
82
|
+
count # => 1
|
83
|
+
@count # => 1
|
84
|
+
|
85
|
+
#in the controller
|
86
|
+
count # => 1
|
87
|
+
@count # => nil
|
88
|
+
|
89
|
+
#in the view
|
90
|
+
count # => 1
|
91
|
+
@count # => nil
|
92
|
+
|
93
|
+
|
94
|
+
### Implicit Controller
|
95
|
+
|
96
|
+
Because controller actions can now be defined outside of the controller, defining the controller is optional. If you
|
97
|
+
do not expcitily define a controller, ActionHero will fall back to the ImplicitController.
|
98
|
+
|
99
|
+
Ensure an implicit controller is defined. Without configuration, the implicit controller defaults to ImplicitController.
|
100
|
+
|
101
|
+
# app/controllers/implicit_controller.rb
|
102
|
+
class ImplicitController < ApplicationController
|
103
|
+
include ActionHero::Controller
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
### Define Several Implicit Controllers and Configure Usage
|
108
|
+
|
109
|
+
In the case you want several implicit controllers due to different use cases, such as web app controller vs API you can
|
110
|
+
define several implicit controllers and configure the usage.
|
111
|
+
|
112
|
+
Define the implicit controllers.
|
113
|
+
|
114
|
+
# app/controllers/implicit_controller.rb
|
115
|
+
class ImplicitController < ApplicationController
|
116
|
+
include ActionHero::Controller
|
117
|
+
end
|
118
|
+
|
119
|
+
# app/controllers/api/v1/implicit_controller.rb
|
120
|
+
class Api::V1::ImplicitController < ApplicationController
|
121
|
+
include ActionHero::Controller
|
122
|
+
end
|
123
|
+
|
124
|
+
Configure the usage. The configuration uses regexs to match against the #controller_name and will use the first one
|
125
|
+
matched, so order matters.
|
126
|
+
|
127
|
+
# config/initializers/action_hero.rb
|
128
|
+
ActionHero.configure do |config|
|
129
|
+
config.implicit_controllers = [
|
130
|
+
[/^\/api\/.*/, Api::ImplicitController],
|
131
|
+
[/^\/.*/, ImplicitController]
|
132
|
+
]
|
133
|
+
end
|
134
|
+
|
135
|
+
### Mix and Match
|
136
|
+
|
137
|
+
You can mix and match usage of ActionHero action classes and standard Rails controller action methods.
|
138
|
+
|
139
|
+
In order to unobtrusively tie in to the controller, ActionHero::Controller implements the #action_missing
|
140
|
+
method. Thus, if you implement both an aciton class and an action method, the action method will win.
|
141
|
+
|
142
|
+
Define a controller with a show action method and define an action class for the index action.
|
143
|
+
|
144
|
+
# app/controllers/things_controller.rb
|
145
|
+
class ThingsController < ApplicationController
|
146
|
+
include ActionHero::Controller
|
147
|
+
|
148
|
+
def show
|
149
|
+
...
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# app/actions/things/index.rb
|
154
|
+
module Things
|
155
|
+
class Index
|
156
|
+
include ActionHero::action
|
157
|
+
|
158
|
+
def call
|
159
|
+
...
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/action-hero.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'action_hero/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "action-hero"
|
8
|
+
spec.version = ActionHero::VERSION
|
9
|
+
spec.authors = ["C. Jason Harrelson"]
|
10
|
+
spec.email = ["jason@lookforwardenterprises.com"]
|
11
|
+
spec.description = %q{Move actions from methods in Rails controllers to action classes.}
|
12
|
+
spec.summary = %q{Move actions from methods in Rails controllers to action classes.}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
|
24
|
+
spec.add_dependency "rails"
|
25
|
+
end
|
data/lib/action-hero.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "action_hero"
|
data/lib/action_hero.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require "action_hero/version"
|
2
|
+
require "dispatcher_ext"
|
3
|
+
|
4
|
+
module ActionHero
|
5
|
+
|
6
|
+
class ActionNotFound < StandardError #:nodoc:
|
7
|
+
end
|
8
|
+
|
9
|
+
autoload :Action, 'action_hero/action'
|
10
|
+
autoload :ActionResolver, 'action_hero/action_resolver'
|
11
|
+
autoload :Configuration, 'action_hero/configuration'
|
12
|
+
autoload :Controller, 'action_hero/controller'
|
13
|
+
autoload :LogSubscriber, 'action_hero/log_subscriber'
|
14
|
+
|
15
|
+
def self.configuration
|
16
|
+
@configuration ||= Configuration.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.configure
|
20
|
+
yield( configuration ) if block_given?
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
ActionHero::LogSubscriber.attach_to :action_controller
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'forwardable'
|
3
|
+
|
4
|
+
module ActionHero
|
5
|
+
module Action
|
6
|
+
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
|
11
|
+
extend Forwardable
|
12
|
+
|
13
|
+
attr_reader :controller
|
14
|
+
protected :controller
|
15
|
+
|
16
|
+
def_delegators :controller, :action_name,
|
17
|
+
:env,
|
18
|
+
:flash,
|
19
|
+
:formats,
|
20
|
+
:head,
|
21
|
+
:headers,
|
22
|
+
:params,
|
23
|
+
:redirect_to,
|
24
|
+
:render,
|
25
|
+
:render_to_string,
|
26
|
+
:request,
|
27
|
+
:reset_session,
|
28
|
+
:respond_with,
|
29
|
+
:response,
|
30
|
+
:session,
|
31
|
+
:url_for,
|
32
|
+
:url_options
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
def initialize( controller )
|
37
|
+
@controller = controller
|
38
|
+
end
|
39
|
+
|
40
|
+
protected
|
41
|
+
|
42
|
+
def expose( *args )
|
43
|
+
name = args.first.is_a?( Symbol ) ? args.first : (raise NotImplementedError)
|
44
|
+
value = args.last
|
45
|
+
instance_variable_set "@#{name}", value
|
46
|
+
controller.send :expose, *args
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module ActionHero
|
2
|
+
class ActionResolver
|
3
|
+
|
4
|
+
attr_reader :module_name,
|
5
|
+
:action_name
|
6
|
+
|
7
|
+
def initialize( options )
|
8
|
+
@module_name = normalize_controller( options )
|
9
|
+
@action_name = options[:action_name]
|
10
|
+
end
|
11
|
+
|
12
|
+
def action_class
|
13
|
+
@action_class ||= action_class_name.constantize
|
14
|
+
end
|
15
|
+
|
16
|
+
def action_class_name
|
17
|
+
@action_class_name ||= [
|
18
|
+
module_name,
|
19
|
+
action_name.camelize
|
20
|
+
].join( '::' )
|
21
|
+
end
|
22
|
+
|
23
|
+
def action_class_file_exists?
|
24
|
+
File.exists?( Rails.root.join( 'app', 'actions', "#{action_class_name.underscore}.rb" ))
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
|
29
|
+
def normalize_controller( options )
|
30
|
+
if options[:controller_const]
|
31
|
+
options[:controller_const].gsub( /Controller$/, '' )
|
32
|
+
elsif options[:controller]
|
33
|
+
options[:controller].classify
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module ActionHero
|
4
|
+
module Controller
|
5
|
+
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
protected
|
9
|
+
|
10
|
+
def expose( *args )
|
11
|
+
name = args.first.is_a?( Symbol ) ? args.first : (raise NotImplementedError)
|
12
|
+
value = args.last
|
13
|
+
data.merge!( name => value )
|
14
|
+
self.class.send( :define_method, name, lambda { data[name] } )
|
15
|
+
self.class.helper_method name
|
16
|
+
value
|
17
|
+
end
|
18
|
+
|
19
|
+
def action_missing( name, *args, &block )
|
20
|
+
begin
|
21
|
+
action_class
|
22
|
+
rescue NoMethodError
|
23
|
+
# protect against misidentification due to
|
24
|
+
# NoMethodError being descendent of NameError
|
25
|
+
raise
|
26
|
+
rescue NameError => ex
|
27
|
+
raise ActionNotFound,
|
28
|
+
"The action #{action_class_name} nor #{self.class.name}##{name} could be found",
|
29
|
+
ex.backtrace
|
30
|
+
end
|
31
|
+
prepend_view_path "#{Rails.root}/app/views/#{params[:controller]}"
|
32
|
+
execute_action
|
33
|
+
end
|
34
|
+
|
35
|
+
# override _normalize_render in order to insert implied controller's view prefix
|
36
|
+
def _normalize_render(*args, &block)
|
37
|
+
options = _normalize_args(*args, &block)
|
38
|
+
_normalize_options(options)
|
39
|
+
unless options[:prefixes].include?( params[:controller] )
|
40
|
+
options[:prefixes].insert( 0, params[:controller] )
|
41
|
+
end
|
42
|
+
options
|
43
|
+
end
|
44
|
+
|
45
|
+
def data
|
46
|
+
@data ||= {}.with_indifferent_access
|
47
|
+
end
|
48
|
+
|
49
|
+
def execute_action
|
50
|
+
action = action_class.new( self )
|
51
|
+
action.call
|
52
|
+
end
|
53
|
+
|
54
|
+
def resolver
|
55
|
+
@resolver ||= ActionResolver.new( :controller_const => "#{params[:controller].classify}Controller",
|
56
|
+
:action_name => action_name )
|
57
|
+
end
|
58
|
+
|
59
|
+
def action_class
|
60
|
+
resolver.action_class
|
61
|
+
end
|
62
|
+
|
63
|
+
def action_class_name
|
64
|
+
resolver.action_class_name
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module ActionHero
|
2
|
+
class LogSubscriber < ActiveSupport::LogSubscriber
|
3
|
+
|
4
|
+
def start_processing( event )
|
5
|
+
controller_name = "#{event.payload[:params]['controller'].camelize}Controller"
|
6
|
+
unless event.payload[:controller] == controller_name
|
7
|
+
info "[ActionHero] No explicit #{controller_name} falling back to #{event.payload[:controller]}"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module ActionDispatch
|
2
|
+
module Routing
|
3
|
+
class RouteSet
|
4
|
+
class Dispatcher
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def controller(params, default_controller=true)
|
9
|
+
if params && params.key?(:controller)
|
10
|
+
controller_param = params[:controller]
|
11
|
+
action_param = params[:action]
|
12
|
+
controller_reference(controller_param, action_param)
|
13
|
+
end
|
14
|
+
rescue NameError => e
|
15
|
+
raise ActionController::RoutingError, e.message, e.backtrace if default_controller
|
16
|
+
end
|
17
|
+
|
18
|
+
def controller_reference(controller_param, action_param)
|
19
|
+
const_name = @controller_class_names[controller_param] ||= "#{controller_param.camelize}Controller"
|
20
|
+
ActiveSupport::Dependencies.constantize(const_name)
|
21
|
+
rescue NoMethodError
|
22
|
+
# protect against misidentification due to
|
23
|
+
# NoMethodError being descendent of NameError
|
24
|
+
raise
|
25
|
+
rescue NameError
|
26
|
+
action_hero_resolver = ActionHero::ActionResolver.new( :controller => controller_param,
|
27
|
+
:action_name => action_param )
|
28
|
+
unless action_hero_resolver.action_class_file_exists?
|
29
|
+
raise
|
30
|
+
end
|
31
|
+
|
32
|
+
controller_const = nil
|
33
|
+
ActionHero.configuration.implicit_controllers.each do |regex, controller|
|
34
|
+
if regex.match( "/#{controller_param}" )
|
35
|
+
controller_const = controller
|
36
|
+
break
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
raise NameError unless controller_const
|
41
|
+
controller_const
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
metadata
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: action-hero
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- C. Jason Harrelson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-09-08 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.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rails
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Move actions from methods in Rails controllers to action classes.
|
56
|
+
email:
|
57
|
+
- jason@lookforwardenterprises.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- .gitignore
|
63
|
+
- Gemfile
|
64
|
+
- LICENSE.txt
|
65
|
+
- README.md
|
66
|
+
- Rakefile
|
67
|
+
- action-hero.gemspec
|
68
|
+
- lib/action-hero.rb
|
69
|
+
- lib/action_hero.rb
|
70
|
+
- lib/action_hero/action.rb
|
71
|
+
- lib/action_hero/action_resolver.rb
|
72
|
+
- lib/action_hero/configuration.rb
|
73
|
+
- lib/action_hero/controller.rb
|
74
|
+
- lib/action_hero/log_subscriber.rb
|
75
|
+
- lib/action_hero/version.rb
|
76
|
+
- lib/dispatcher_ext.rb
|
77
|
+
homepage: ''
|
78
|
+
licenses:
|
79
|
+
- MIT
|
80
|
+
metadata: {}
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options: []
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - '>='
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
requirements: []
|
96
|
+
rubyforge_project:
|
97
|
+
rubygems_version: 2.0.5
|
98
|
+
signing_key:
|
99
|
+
specification_version: 4
|
100
|
+
summary: Move actions from methods in Rails controllers to action classes.
|
101
|
+
test_files: []
|