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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d42f5e13fe369f5658137e5442ad8074827a6093
4
- data.tar.gz: 1ffcc823623757e1cc509831f7bb834c436112ac
3
+ metadata.gz: 80ec9cfa13cc143a616c0953168c6fc6c2b59fea
4
+ data.tar.gz: 850b188e163e61cce52c531378474690b8c80579
5
5
  SHA512:
6
- metadata.gz: ab77feaaaf6fad427084fdcb666d25b409fd4aa6e54b46a4552f6d0999a5eac3255e1d08fee98a6f9172134c37ec080c754be7e481e4324554eb3d454ad61251
7
- data.tar.gz: 12656d677d4f7c26dfc045d167826a20474b5bc2abb9171092aa4fbf48b100c82394020e6248c6bb1514c4a144d7cf2f21d5d23f0bfd006c8550fd42c2493d52
6
+ metadata.gz: 366e7e2722086aa9f2ff20f1aea4f96e55a4fba310ae7cd9bd81c729cc2e1160961e28174f6827271be70300052846a3239c051177a1ab75f03331775f4906b5
7
+ data.tar.gz: 73eb44ecc2fd1dbd8a64985c97a06674df295f5e348fbbc4f20f9290b2ade2bac4f61c4c58607aff25ff176ded33a71b001dfd7d57bd4f8f8476deba453143d2
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 1.3.2 ##
2
+
3
+ * Autoloading mechanism added
4
+
1
5
  ## 1.3.1 ##
2
6
 
3
7
  * Upgrade to Rails 4.1 and RSpec 3.1
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- class-action (1.3.0)
4
+ class-action (1.3.1)
5
5
  activesupport
6
6
 
7
7
  GEM
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
 
@@ -1,3 +1,3 @@
1
1
  module ClassAction
2
- VERSION = "1.3.1"
2
+ VERSION = "1.3.2"
3
3
  end
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 || const_get("#{action.to_s.camelize}Action")
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)
@@ -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 } }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: class-action
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joost Lubach