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 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