class-action 1.3.1 → 1.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/Gemfile.lock +1 -1
- data/README.md +21 -1
- data/lib/class_action/version.rb +1 -1
- data/lib/class_action.rb +45 -1
- data/spec/class_action_spec.rb +58 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 80ec9cfa13cc143a616c0953168c6fc6c2b59fea
|
4
|
+
data.tar.gz: 850b188e163e61cce52c531378474690b8c80579
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 366e7e2722086aa9f2ff20f1aea4f96e55a4fba310ae7cd9bd81c729cc2e1160961e28174f6827271be70300052846a3239c051177a1ab75f03331775f4906b5
|
7
|
+
data.tar.gz: 73eb44ecc2fd1dbd8a64985c97a06674df295f5e348fbbc4f20f9290b2ade2bac4f61c4c58607aff25ff176ded33a71b001dfd7d57bd4f8f8476deba453143d2
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -37,6 +37,26 @@ In your controller, make sure you have included `ClassAction`, and declare which
|
|
37
37
|
class_action :show
|
38
38
|
end
|
39
39
|
|
40
|
+
### Organize your files
|
41
|
+
|
42
|
+
ClassAction comes with an autoloading mechanism for actions. If you have the following file structure:
|
43
|
+
|
44
|
+
- app
|
45
|
+
|- controllers
|
46
|
+
|- posts_controller.rb
|
47
|
+
|- actions
|
48
|
+
|- index_action.rb
|
49
|
+
|- show_action.rb
|
50
|
+
|
51
|
+
You need to tell ClassAction where the actions are located. You can do that by setting variable `action_load_path`:
|
52
|
+
|
53
|
+
class PostsController
|
54
|
+
include ClassAction
|
55
|
+
self.action_load_path << File.expand_path('../actions/*.rb', __FILE__)
|
56
|
+
|
57
|
+
class_action :index, :show
|
58
|
+
end
|
59
|
+
|
40
60
|
### Create an action
|
41
61
|
|
42
62
|
Then, create your `show` action class (the default is to name this class `PostsController::Show`, but you may customize this).
|
@@ -117,7 +137,7 @@ However, `ClassAction` provides a bit more support for responses. You may define
|
|
117
137
|
|
118
138
|
end
|
119
139
|
|
120
|
-
This employs the use of `ActionController#respond_to`. Additionally, there is support for the Rails 3 style `respond_with`. To illustrate, this:
|
140
|
+
This employs the use of `ActionController#respond_to`. Additionally, there is support for the Rails 3+ style `respond_with`. To illustrate, this:
|
121
141
|
|
122
142
|
class Show < ClassAction::Action
|
123
143
|
|
data/lib/class_action/version.rb
CHANGED
data/lib/class_action.rb
CHANGED
@@ -8,6 +8,7 @@ module ClassAction
|
|
8
8
|
class << self
|
9
9
|
def included(target)
|
10
10
|
target.extend ClassMethods
|
11
|
+
target.action_load_path = []
|
11
12
|
setup target
|
12
13
|
end
|
13
14
|
|
@@ -22,9 +23,11 @@ module ClassAction
|
|
22
23
|
|
23
24
|
module ClassMethods
|
24
25
|
|
26
|
+
attr_accessor :action_load_path
|
27
|
+
|
25
28
|
def class_action(*actions, klass: nil)
|
26
29
|
actions.each do |action|
|
27
|
-
action_class = klass ||
|
30
|
+
action_class = klass || find_action_class(action)
|
28
31
|
raise ArgumentError, "ClassAction does not support anonymous classes" if action_class.name.nil?
|
29
32
|
|
30
33
|
class_eval <<-RUBY, __FILE__, __LINE__+1
|
@@ -58,8 +61,49 @@ module ClassAction
|
|
58
61
|
end
|
59
62
|
end
|
60
63
|
|
64
|
+
protected
|
65
|
+
|
66
|
+
def find_action_class(action)
|
67
|
+
class_name = "#{action.to_s.camelize}Action"
|
68
|
+
return const_get(class_name) if const_defined?(class_name)
|
69
|
+
|
70
|
+
if action_load_path.present?
|
71
|
+
load_action_class action
|
72
|
+
else
|
73
|
+
raise LoadError, "action class #{name}::#{class_name} not found and no action_load_path defined"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
61
77
|
private
|
62
78
|
|
79
|
+
def load_action_class(action)
|
80
|
+
basename = "#{action}_action"
|
81
|
+
|
82
|
+
path = path_for_action(basename) or
|
83
|
+
raise LoadError, "file '#{basename}.rb' not found in the load path for #{name}"
|
84
|
+
|
85
|
+
# Require the path
|
86
|
+
ActiveSupport::Dependencies.require path
|
87
|
+
|
88
|
+
# Try again
|
89
|
+
class_name = basename.camelize
|
90
|
+
if const_defined?(class_name)
|
91
|
+
const_get(class_name)
|
92
|
+
else
|
93
|
+
raise LoadError, "expected file '#{path}' to define action class #{class_name} but it was not defined"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def path_for_action(basename)
|
98
|
+
[*action_load_path].each do |path|
|
99
|
+
path = Dir.glob(path).find do |p|
|
100
|
+
File.basename(p, '.rb') == basename
|
101
|
+
end
|
102
|
+
return path if path
|
103
|
+
end
|
104
|
+
nil
|
105
|
+
end
|
106
|
+
|
63
107
|
# Injects the mimes (formats) that the action responds to into the controller
|
64
108
|
# mimes_for_respond_to hash.
|
65
109
|
def inject_class_action_mimes(action, klass)
|
data/spec/class_action_spec.rb
CHANGED
@@ -22,6 +22,64 @@ describe ClassAction do
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
+
describe 'lazy loading' do
|
26
|
+
|
27
|
+
let(:action_load_path) { %w(app/controllers/my_controller/actions/*.rb app/controllers/my_controller/other_actions/*.rb) }
|
28
|
+
|
29
|
+
before do
|
30
|
+
# Fake three files
|
31
|
+
allow(Dir).to receive(:glob).with(action_load_path[0]).and_return(
|
32
|
+
['app/controllers/my_controller/actions/first_action.rb']
|
33
|
+
)
|
34
|
+
allow(Dir).to receive(:glob).with(action_load_path[1]).and_return(
|
35
|
+
['app/controllers/my_controller/actions/second_action.rb', 'app/controllers/my_controller/actions/third_action.rb']
|
36
|
+
)
|
37
|
+
|
38
|
+
allow(ActiveSupport::Dependencies).to receive(:require) do |arg|
|
39
|
+
case arg
|
40
|
+
when 'app/controllers/my_controller/actions/first_action.rb'
|
41
|
+
class ::ClassActionTestController::FirstAction < ActionController::Base; end
|
42
|
+
|
43
|
+
when 'app/controllers/my_controller/actions/second_action.rb'
|
44
|
+
# Incorrect name
|
45
|
+
class ::ClassActionTestController::NotSecondAction < ActionController::Base; end
|
46
|
+
|
47
|
+
when 'app/controllers/my_controller/actions/third_action.rb'
|
48
|
+
class ::ClassActionTestController::ThirdAction < ActionController::Base; end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
before do
|
54
|
+
allow(ClassActionTestController).to receive(:action_load_path).and_return(action_load_path)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should raise an error if the class is not found and no load path is specified" do
|
58
|
+
allow(ClassActionTestController).to receive(:action_load_path).and_return([])
|
59
|
+
expect { ClassActionTestController.send(:find_action_class, :first) }
|
60
|
+
.to raise_error("action class ClassActionTestController::FirstAction not found and no action_load_path defined")
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should find FirstAction" do
|
64
|
+
expect(ClassActionTestController.send(:find_action_class, :first)).to be(ClassActionTestController::FirstAction)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should find ThirdAction" do
|
68
|
+
expect(ClassActionTestController.send(:find_action_class, :third)).to be(ClassActionTestController::ThirdAction)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should raise an error if no file was found in the load path" do
|
72
|
+
expect { ClassActionTestController.send(:find_action_class, :fourth) }
|
73
|
+
.to raise_error(LoadError, "file 'fourth_action.rb' not found in the load path for ClassActionTestController")
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should raise an error on second as the wrong class is defined there" do
|
77
|
+
expect { ClassActionTestController.send(:find_action_class, :second) }
|
78
|
+
.to raise_error(LoadError, "expected file 'app/controllers/my_controller/actions/second_action.rb' to define action class SecondAction but it was not defined")
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
25
83
|
context "adding a class action :show" do
|
26
84
|
|
27
85
|
before { ClassActionTestController.class_eval { class_action :show } }
|