class-action 1.3.1 → 1.3.2
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 +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 } }
|