rails_inheritable_attributes_manager 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +13 -0
- data/LICENSE +19 -0
- data/README.markdown +33 -0
- data/RELEASE_NOTES +8 -0
- data/Rakefile +8 -0
- data/VERSION +1 -0
- data/init.rb +1 -0
- data/lib/controllers/controller_filters.rb +57 -0
- data/lib/models/nested_attributes.rb +27 -0
- data/lib/rails_inheritable_attributes_manager.rb +2 -0
- data/tests/controllers/append_after_test.rb +42 -0
- data/tests/controllers/append_around_test.rb +42 -0
- data/tests/controllers/append_before_test.rb +53 -0
- data/tests/controllers/deep_class_hierarchy_test.rb +61 -0
- data/tests/controllers/normal_filter_chain_test.rb +56 -0
- data/tests/controllers/prepend_after_test.rb +42 -0
- data/tests/controllers/prepend_around_test.rb +42 -0
- data/tests/controllers/prepend_before_test.rb +42 -0
- data/tests/controllers/skip_after_test.rb +43 -0
- data/tests/controllers/skip_before_test.rb +43 -0
- data/tests/controllers/skip_test.rb +43 -0
- data/tests/models/accepts_nested_attributes_for_test.rb +33 -0
- data/tests/models/config.rb +41 -0
- data/tests/test_helper.rb +45 -0
- metadata +154 -0
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2009,2010 Ryan L. Bell
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# Inheritable Attributes Manager for Rails
|
2
|
+
|
3
|
+
Inheritable Attributes Manager makes sure that those magic rails bits (filters, nestested associations, etc.) make it into your subclasses, regardless of the order the code is loaded.
|
4
|
+
|
5
|
+
## Install
|
6
|
+
|
7
|
+
As a plugin:
|
8
|
+
|
9
|
+
./script/plugin install git://github.com/kofno/rails_inheritable_attributes_manager.git
|
10
|
+
|
11
|
+
As a gem:
|
12
|
+
|
13
|
+
gem install rails_inheritable_attributes_manager
|
14
|
+
|
15
|
+
And don't forget to add the gem to your rails config
|
16
|
+
|
17
|
+
config.gem "rails_inheritable_attributes_manager"
|
18
|
+
|
19
|
+
## Links
|
20
|
+
|
21
|
+
* [Wiki](http://wiki.github.com/kofno/rails_inheritable_attributes_manager)
|
22
|
+
* [Issues](http://github.com/kofno/rails_inheritable_attributes_manager/issues)
|
23
|
+
|
24
|
+
## Why would I need this?
|
25
|
+
|
26
|
+
You may not. In general, the Rails community tends to treat plugins as extensions to Rails, and application code builds on Rails and the plugins. For this scenario, the default inheritable attributes behavior is fine.
|
27
|
+
|
28
|
+
Of course, the other use of plugins is to extend the application's functionality. When writing an extension, its quite common to re-open the application classes (controllers, STI models, etc.) and add filters or associations. In this scenario, depending on how the code loads, subclasses may not receive the new functionality. This is exactly the scenario inheritable attributes manager was created to fix.
|
29
|
+
|
30
|
+
[More information on inheritable attributes and filter chains](http://wiki.github.com/kofno/rails_inheritable_attributes_manager/rails-inheritable-attributes)
|
31
|
+
|
32
|
+
[How it works](http://wiki.github.com/kofno/rails_inheritable_attributes_manager/how-it-works)
|
33
|
+
|
data/RELEASE_NOTES
ADDED
data/Rakefile
ADDED
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.0
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'rails_inheritable_attributes_manager'
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'action_controller'
|
2
|
+
|
3
|
+
module ActionController
|
4
|
+
|
5
|
+
class Base
|
6
|
+
class << self
|
7
|
+
def self.record_filter_chain_ops_for(*filter_methods)
|
8
|
+
filter_methods.each do |meth|
|
9
|
+
class_eval <<-CODE
|
10
|
+
def #{meth}_with_recording(*filters, &block)
|
11
|
+
filter_operation = lambda { #{meth}_without_recording(*filters, &block) }
|
12
|
+
filter_operation.call
|
13
|
+
recorded_filter_chain_ops << filter_operation
|
14
|
+
refresh_subclass_filter_chains
|
15
|
+
end
|
16
|
+
alias_method_chain meth, :recording
|
17
|
+
CODE
|
18
|
+
end
|
19
|
+
end
|
20
|
+
record_filter_chain_ops_for :append_before_filter, :before_filter
|
21
|
+
record_filter_chain_ops_for :append_after_filter, :after_filter
|
22
|
+
record_filter_chain_ops_for :append_around_filter, :around_filter
|
23
|
+
record_filter_chain_ops_for :prepend_before_filter, :prepend_after_filter, :prepend_around_filter
|
24
|
+
record_filter_chain_ops_for :skip_before_filter, :skip_after_filter, :skip_filter
|
25
|
+
|
26
|
+
def refresh_subclass_filter_chains
|
27
|
+
immediate_subclasses.each do |child|
|
28
|
+
child.write_inheritable_attribute('filter_chain', filter_chain.dup)
|
29
|
+
child.replay_filter_chain_ops
|
30
|
+
child.refresh_subclass_filter_chains
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def replay_filter_chain_ops
|
35
|
+
recorded_filter_chain_ops.each { |filter_chain_op| filter_chain_op.call }
|
36
|
+
end
|
37
|
+
|
38
|
+
def immediate_subclasses
|
39
|
+
@immediate_subclasses ||= []
|
40
|
+
end
|
41
|
+
|
42
|
+
def inherited_with_subclass_recording(child)
|
43
|
+
immediate_subclasses << child
|
44
|
+
inherited_without_subclass_recording(child)
|
45
|
+
end
|
46
|
+
alias_method_chain :inherited, :subclass_recording
|
47
|
+
|
48
|
+
def recorded_filter_chain_ops
|
49
|
+
@recorded_filter_chain_ops ||= []
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
|
5
|
+
class Base
|
6
|
+
class << self
|
7
|
+
def accepts_nested_attributes_for_with_inheritance_management(*attr_names)
|
8
|
+
accepts_nested_attributes_for_without_inheritance_management(*attr_names)
|
9
|
+
alert_subclasses_of_new_nested_attributes
|
10
|
+
end
|
11
|
+
alias_method_chain :accepts_nested_attributes_for, :inheritance_management
|
12
|
+
|
13
|
+
def alert_subclasses_of_new_nested_attributes
|
14
|
+
subclasses.each do |subclass|
|
15
|
+
subclass.superclass_received_nested_attributes(nested_attributes_options)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def superclass_received_nested_attributes(super_nested_attr_options)
|
20
|
+
nested_attributes_options.update(super_nested_attr_options) do |hash, oldval, newval|
|
21
|
+
oldval.nil? ? newval : oldval
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class AfterFiltersTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
class ApplicationController < ::ActionController::Base
|
6
|
+
after_filter :application_filter
|
7
|
+
end
|
8
|
+
|
9
|
+
class ChildController < ApplicationController
|
10
|
+
after_filter :child_filter
|
11
|
+
end
|
12
|
+
|
13
|
+
ApplicationController.class_eval do
|
14
|
+
after_filter :after_thought
|
15
|
+
end
|
16
|
+
|
17
|
+
context "The ApplicationController" do
|
18
|
+
setup do
|
19
|
+
@app_filter_chain = ApplicationController.filter_chain
|
20
|
+
end
|
21
|
+
|
22
|
+
should "have only its own filters" do
|
23
|
+
assert_contains_filter @app_filter_chain, :application_filter
|
24
|
+
assert_contains_filter @app_filter_chain, :after_thought
|
25
|
+
assert_equal 2, @app_filter_chain.size
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
context "The ChildController" do
|
31
|
+
setup do
|
32
|
+
@child_filter_chain = ChildController.filter_chain
|
33
|
+
end
|
34
|
+
|
35
|
+
should "should have its own filter, plus the inherited ones" do
|
36
|
+
assert_contains_filter @child_filter_chain, :application_filter
|
37
|
+
assert_contains_filter @child_filter_chain, :after_thought
|
38
|
+
assert_contains_filter @child_filter_chain, :child_filter
|
39
|
+
assert_equal 3, @child_filter_chain.size
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class AppendAroundTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
class ApplicationController < ::ActionController::Base
|
6
|
+
around_filter :application_filter
|
7
|
+
end
|
8
|
+
|
9
|
+
class ChildController < ApplicationController
|
10
|
+
around_filter :child_filter
|
11
|
+
end
|
12
|
+
|
13
|
+
ApplicationController.class_eval do
|
14
|
+
around_filter :after_thought
|
15
|
+
end
|
16
|
+
|
17
|
+
context "The ApplicationController" do
|
18
|
+
setup do
|
19
|
+
@app_filter_chain = ApplicationController.filter_chain
|
20
|
+
end
|
21
|
+
|
22
|
+
should "have only its own filters" do
|
23
|
+
assert_contains_filter @app_filter_chain, :application_filter
|
24
|
+
assert_contains_filter @app_filter_chain, :after_thought
|
25
|
+
assert_equal 2, @app_filter_chain.size
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
context "The ChildController" do
|
31
|
+
setup do
|
32
|
+
@child_filter_chain = ChildController.filter_chain
|
33
|
+
end
|
34
|
+
|
35
|
+
should "should have its own filter, plus the inherited ones" do
|
36
|
+
assert_contains_filter @child_filter_chain, :application_filter
|
37
|
+
assert_contains_filter @child_filter_chain, :after_thought
|
38
|
+
assert_contains_filter @child_filter_chain, :child_filter
|
39
|
+
assert_equal 3, @child_filter_chain.size
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ReopenParentControllerFilterChainTest < Test::Unit::TestCase
|
4
|
+
# build our test classes
|
5
|
+
class ApplicationController < ::ActionController::Base
|
6
|
+
before_filter :application_filter
|
7
|
+
def application_filter; puts "something"; end
|
8
|
+
end
|
9
|
+
|
10
|
+
class ChildController < ApplicationController
|
11
|
+
before_filter :child_filter
|
12
|
+
def child_filter; puts "from the mouths of babes";end
|
13
|
+
end
|
14
|
+
|
15
|
+
# now we reload
|
16
|
+
ApplicationController.class_eval do
|
17
|
+
before_filter :new_stuff_baby
|
18
|
+
def new_stuff_baby; puts "yeah!"; end
|
19
|
+
end
|
20
|
+
|
21
|
+
def app_filter_chain
|
22
|
+
ApplicationController.filter_chain
|
23
|
+
end
|
24
|
+
|
25
|
+
def child_filter_chain
|
26
|
+
ChildController.filter_chain
|
27
|
+
end
|
28
|
+
|
29
|
+
context "The ApplicationController" do
|
30
|
+
|
31
|
+
should "have a two filters" do
|
32
|
+
assert_equal 2, app_filter_chain.size
|
33
|
+
end
|
34
|
+
|
35
|
+
should "have a filter named :new_stuff_baby" do
|
36
|
+
assert_contains_filter app_filter_chain, :new_stuff_baby
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
context "The ChildController" do
|
42
|
+
|
43
|
+
should "have a three filters" do
|
44
|
+
assert_equal 3, child_filter_chain.size
|
45
|
+
end
|
46
|
+
|
47
|
+
should "have a filter named :new_stuff_baby" do
|
48
|
+
assert_contains_filter child_filter_chain, :new_stuff_baby
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class DeepClassHierarchyTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
class ApplicationController < ::ActionController::Base
|
6
|
+
after_filter :application_filter
|
7
|
+
end
|
8
|
+
|
9
|
+
class ChildController < ApplicationController
|
10
|
+
before_filter :child_filter
|
11
|
+
skip_filter :after_thought
|
12
|
+
end
|
13
|
+
|
14
|
+
ApplicationController.class_eval do
|
15
|
+
around_filter :after_thought
|
16
|
+
before_filter { puts "poo" }
|
17
|
+
end
|
18
|
+
|
19
|
+
class SubChildController < ChildController
|
20
|
+
append_before_filter :sub_filter
|
21
|
+
skip_after_filter :application_filter
|
22
|
+
end
|
23
|
+
|
24
|
+
ChildController.class_eval do
|
25
|
+
append_after_filter :late_arrival
|
26
|
+
append_around_filter :gets_around
|
27
|
+
prepend_before_filter :line_cutter
|
28
|
+
end
|
29
|
+
|
30
|
+
context "The ApplicationController" do
|
31
|
+
setup do
|
32
|
+
@app_filter_chain = ApplicationController.filter_chain
|
33
|
+
end
|
34
|
+
|
35
|
+
should "have only its own filters" do
|
36
|
+
assert_chain_order [:after_thought, :a_proc, :application_filter], @app_filter_chain
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
context "The ChildController" do
|
42
|
+
setup do
|
43
|
+
@child_filter_chain = ChildController.filter_chain
|
44
|
+
end
|
45
|
+
|
46
|
+
should "should have its own filter, plus the inherited ones" do
|
47
|
+
assert_chain_order [:line_cutter, :a_proc, :child_filter, :gets_around, :application_filter, :late_arrival], @child_filter_chain
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "The SubChildController" do
|
52
|
+
setup do
|
53
|
+
@sub_child_filter_chain = SubChildController.filter_chain
|
54
|
+
end
|
55
|
+
|
56
|
+
should "should have its own filter, plus the inherited ones" do
|
57
|
+
assert_chain_order [:line_cutter, :a_proc, :child_filter, :gets_around, :sub_filter, :late_arrival], @sub_child_filter_chain
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
# captures normal, healthy filter_chain behavior
|
4
|
+
class NormalFilterChainTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
# build our test classes
|
7
|
+
class ApplicationController < ::ActionController::Base
|
8
|
+
before_filter :application_filter
|
9
|
+
def application_filter; puts "something"; end
|
10
|
+
end
|
11
|
+
|
12
|
+
class ChildController < ApplicationController
|
13
|
+
before_filter :child_filter
|
14
|
+
def child_filter; puts "from the mouths of babes";end
|
15
|
+
end
|
16
|
+
|
17
|
+
def app_filter_chain
|
18
|
+
ApplicationController.filter_chain
|
19
|
+
end
|
20
|
+
|
21
|
+
def child_filter_chain
|
22
|
+
ChildController.filter_chain
|
23
|
+
end
|
24
|
+
|
25
|
+
context "The ApplicationController" do
|
26
|
+
|
27
|
+
should "inherited filters be the same" do
|
28
|
+
assert_equal app_filter_chain.first, child_filter_chain.first
|
29
|
+
end
|
30
|
+
|
31
|
+
should 'have one filter' do
|
32
|
+
assert_equal 1, app_filter_chain.size
|
33
|
+
end
|
34
|
+
|
35
|
+
should 'have a filter named :application_filter' do
|
36
|
+
assert_contains_filter app_filter_chain, :application_filter
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "The ChildController" do
|
41
|
+
|
42
|
+
should 'have two filters' do
|
43
|
+
assert_equal 2, child_filter_chain.size
|
44
|
+
end
|
45
|
+
|
46
|
+
should 'have a filter named :application_filter' do
|
47
|
+
assert_contains_filter child_filter_chain, :application_filter
|
48
|
+
end
|
49
|
+
|
50
|
+
should 'have a filter named :child_filter' do
|
51
|
+
assert_contains_filter child_filter_chain, :child_filter
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class PrependAfterTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
class ApplicationController < ::ActionController::Base
|
6
|
+
prepend_after_filter :application_filter
|
7
|
+
end
|
8
|
+
|
9
|
+
class ChildController < ApplicationController
|
10
|
+
prepend_after_filter :child_filter
|
11
|
+
end
|
12
|
+
|
13
|
+
ApplicationController.class_eval do
|
14
|
+
prepend_after_filter :after_thought
|
15
|
+
end
|
16
|
+
|
17
|
+
context "The ApplicationController" do
|
18
|
+
setup do
|
19
|
+
@app_filter_chain = ApplicationController.filter_chain
|
20
|
+
end
|
21
|
+
|
22
|
+
should "have only its own filters" do
|
23
|
+
assert_contains_filter @app_filter_chain, :application_filter
|
24
|
+
assert_contains_filter @app_filter_chain, :after_thought
|
25
|
+
assert_equal 2, @app_filter_chain.size
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
context "The ChildController" do
|
31
|
+
setup do
|
32
|
+
@child_filter_chain = ChildController.filter_chain
|
33
|
+
end
|
34
|
+
|
35
|
+
should "should have its own filter, plus the inherited ones" do
|
36
|
+
assert_contains_filter @child_filter_chain, :application_filter
|
37
|
+
assert_contains_filter @child_filter_chain, :after_thought
|
38
|
+
assert_contains_filter @child_filter_chain, :child_filter
|
39
|
+
assert_equal 3, @child_filter_chain.size
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class PrependAroundTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
class ApplicationController < ::ActionController::Base
|
6
|
+
prepend_around_filter :application_filter
|
7
|
+
end
|
8
|
+
|
9
|
+
class ChildController < ApplicationController
|
10
|
+
prepend_around_filter :child_filter
|
11
|
+
end
|
12
|
+
|
13
|
+
ApplicationController.class_eval do
|
14
|
+
prepend_around_filter :after_thought
|
15
|
+
end
|
16
|
+
|
17
|
+
context "The ApplicationController" do
|
18
|
+
setup do
|
19
|
+
@app_filter_chain = ApplicationController.filter_chain
|
20
|
+
end
|
21
|
+
|
22
|
+
should "have only its own filters" do
|
23
|
+
assert_contains_filter @app_filter_chain, :application_filter
|
24
|
+
assert_contains_filter @app_filter_chain, :after_thought
|
25
|
+
assert_equal 2, @app_filter_chain.size
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
context "The ChildController" do
|
31
|
+
setup do
|
32
|
+
@child_filter_chain = ChildController.filter_chain
|
33
|
+
end
|
34
|
+
|
35
|
+
should "should have its own filter, plus the inherited ones" do
|
36
|
+
assert_contains_filter @child_filter_chain, :application_filter
|
37
|
+
assert_contains_filter @child_filter_chain, :after_thought
|
38
|
+
assert_contains_filter @child_filter_chain, :child_filter
|
39
|
+
assert_equal 3, @child_filter_chain.size
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class PrependBeforeTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
class ApplicationController < ::ActionController::Base
|
6
|
+
prepend_before_filter :application_filter
|
7
|
+
end
|
8
|
+
|
9
|
+
class ChildController < ApplicationController
|
10
|
+
prepend_before_filter :child_filter
|
11
|
+
end
|
12
|
+
|
13
|
+
ApplicationController.class_eval do
|
14
|
+
prepend_before_filter :after_thought
|
15
|
+
end
|
16
|
+
|
17
|
+
context "The ApplicationController" do
|
18
|
+
setup do
|
19
|
+
@app_filter_chain = ApplicationController.filter_chain
|
20
|
+
end
|
21
|
+
|
22
|
+
should "have only its own filters" do
|
23
|
+
assert_contains_filter @app_filter_chain, :application_filter
|
24
|
+
assert_contains_filter @app_filter_chain, :after_thought
|
25
|
+
assert_equal 2, @app_filter_chain.size
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
context "The ChildController" do
|
31
|
+
setup do
|
32
|
+
@child_filter_chain = ChildController.filter_chain
|
33
|
+
end
|
34
|
+
|
35
|
+
should "should have its own filter, plus the inherited ones" do
|
36
|
+
assert_contains_filter @child_filter_chain, :application_filter
|
37
|
+
assert_contains_filter @child_filter_chain, :after_thought
|
38
|
+
assert_contains_filter @child_filter_chain, :child_filter
|
39
|
+
assert_equal 3, @child_filter_chain.size
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class SkipAfterTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
class ApplicationController < ::ActionController::Base
|
6
|
+
after_filter :application_filter
|
7
|
+
end
|
8
|
+
|
9
|
+
class ChildController < ApplicationController
|
10
|
+
after_filter :child_filter
|
11
|
+
skip_after_filter :after_thought
|
12
|
+
end
|
13
|
+
|
14
|
+
ApplicationController.class_eval do
|
15
|
+
after_filter :after_thought
|
16
|
+
end
|
17
|
+
|
18
|
+
context "The ApplicationController" do
|
19
|
+
setup do
|
20
|
+
@app_filter_chain = ApplicationController.filter_chain
|
21
|
+
end
|
22
|
+
|
23
|
+
should "have only its own filters" do
|
24
|
+
assert_contains_filter @app_filter_chain, :application_filter
|
25
|
+
assert_contains_filter @app_filter_chain, :after_thought
|
26
|
+
assert_equal 2, @app_filter_chain.size
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
context "The ChildController" do
|
32
|
+
setup do
|
33
|
+
@child_filter_chain = ChildController.filter_chain
|
34
|
+
end
|
35
|
+
|
36
|
+
should "should have its own filter, plus the inherited ones" do
|
37
|
+
assert_contains_filter @child_filter_chain, :application_filter
|
38
|
+
assert_filter_absent @child_filter_chain, :after_thought
|
39
|
+
assert_contains_filter @child_filter_chain, :child_filter
|
40
|
+
assert_equal 2, @child_filter_chain.size
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class SkipBeforeTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
class ApplicationController < ::ActionController::Base
|
6
|
+
before_filter :application_filter
|
7
|
+
end
|
8
|
+
|
9
|
+
class ChildController < ApplicationController
|
10
|
+
before_filter :child_filter
|
11
|
+
skip_before_filter :after_thought
|
12
|
+
end
|
13
|
+
|
14
|
+
ApplicationController.class_eval do
|
15
|
+
before_filter :after_thought
|
16
|
+
end
|
17
|
+
|
18
|
+
context "The ApplicationController" do
|
19
|
+
setup do
|
20
|
+
@app_filter_chain = ApplicationController.filter_chain
|
21
|
+
end
|
22
|
+
|
23
|
+
should "have only its own filters" do
|
24
|
+
assert_contains_filter @app_filter_chain, :application_filter
|
25
|
+
assert_contains_filter @app_filter_chain, :after_thought
|
26
|
+
assert_equal 2, @app_filter_chain.size
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
context "The ChildController" do
|
32
|
+
setup do
|
33
|
+
@child_filter_chain = ChildController.filter_chain
|
34
|
+
end
|
35
|
+
|
36
|
+
should "should have its own filter, plus the inherited ones" do
|
37
|
+
assert_contains_filter @child_filter_chain, :application_filter
|
38
|
+
assert_filter_absent @child_filter_chain, :after_thought
|
39
|
+
assert_contains_filter @child_filter_chain, :child_filter
|
40
|
+
assert_equal 2, @child_filter_chain.size
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class SkipTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
class ApplicationController < ::ActionController::Base
|
6
|
+
after_filter :application_filter
|
7
|
+
end
|
8
|
+
|
9
|
+
class ChildController < ApplicationController
|
10
|
+
before_filter :child_filter
|
11
|
+
skip_filter :after_thought
|
12
|
+
end
|
13
|
+
|
14
|
+
ApplicationController.class_eval do
|
15
|
+
around_filter :after_thought
|
16
|
+
end
|
17
|
+
|
18
|
+
context "The ApplicationController" do
|
19
|
+
setup do
|
20
|
+
@app_filter_chain = ApplicationController.filter_chain
|
21
|
+
end
|
22
|
+
|
23
|
+
should "have only its own filters" do
|
24
|
+
assert_contains_filter @app_filter_chain, :application_filter
|
25
|
+
assert_contains_filter @app_filter_chain, :after_thought
|
26
|
+
assert_equal 2, @app_filter_chain.size
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
context "The ChildController" do
|
32
|
+
setup do
|
33
|
+
@child_filter_chain = ChildController.filter_chain
|
34
|
+
end
|
35
|
+
|
36
|
+
should "should have its own filter, plus the inherited ones" do
|
37
|
+
assert_contains_filter @child_filter_chain, :application_filter
|
38
|
+
assert_filter_absent @child_filter_chain, :after_thought
|
39
|
+
assert_contains_filter @child_filter_chain, :child_filter
|
40
|
+
assert_equal 2, @child_filter_chain.size
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'models/config'
|
3
|
+
|
4
|
+
class AcceptsNestedAttributesForTest < Test::Unit::TestCase
|
5
|
+
include MammalSample
|
6
|
+
|
7
|
+
context "Assigning legs to the dog" do
|
8
|
+
setup do
|
9
|
+
initialize_db
|
10
|
+
create_mammals
|
11
|
+
create_legs
|
12
|
+
|
13
|
+
Mammal.class_eval do
|
14
|
+
has_many :legs
|
15
|
+
accepts_nested_attributes_for :legs, :reject_if => :all_blank
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
should "not fail if legs association added to re-opened Mammal class" do
|
20
|
+
assert_nothing_raised do
|
21
|
+
Dog.new :legs_attributes => [ { :length => :reach_ground } ]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
should "support nested attributes on all descendent classes" do
|
26
|
+
assert_nothing_raised do
|
27
|
+
Beagle.new :legs_attributes => [ { :length => :awfully_short } ]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'sqlite3'
|
2
|
+
|
3
|
+
module MammalSample
|
4
|
+
|
5
|
+
DATABASE_NAME = '.mammal.db'
|
6
|
+
|
7
|
+
class Leg < ActiveRecord::Base
|
8
|
+
end
|
9
|
+
|
10
|
+
class Mammal < ActiveRecord::Base
|
11
|
+
end
|
12
|
+
|
13
|
+
class Dog < Mammal
|
14
|
+
end
|
15
|
+
|
16
|
+
class Beagle < Dog
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize_db
|
20
|
+
SQLite3::Database.new(DATABASE_NAME)
|
21
|
+
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3',
|
22
|
+
:database => DATABASE_NAME)
|
23
|
+
end
|
24
|
+
|
25
|
+
def create_mammals
|
26
|
+
return if Mammal.table_exists?
|
27
|
+
ActiveRecord::Base.connection.create_table :mammals do |t|
|
28
|
+
t.string :type
|
29
|
+
t.timestamps
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def create_legs
|
34
|
+
return if Leg.table_exists?
|
35
|
+
ActiveRecord::Base.connection.create_table :legs do |t|
|
36
|
+
t.string :length
|
37
|
+
t.timestamps
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
# tests are now awesome
|
5
|
+
gem 'shoulda'
|
6
|
+
require 'shoulda'
|
7
|
+
|
8
|
+
# pretty colors
|
9
|
+
gem 'redgreen'
|
10
|
+
require 'redgreen'
|
11
|
+
|
12
|
+
# need some rails bits
|
13
|
+
gem 'actionpack'
|
14
|
+
require 'action_controller'
|
15
|
+
|
16
|
+
gem 'activerecord'
|
17
|
+
require 'active_record'
|
18
|
+
|
19
|
+
#my bits
|
20
|
+
require 'rails_inheritable_attributes_manager'
|
21
|
+
|
22
|
+
# some useful assertions
|
23
|
+
|
24
|
+
def assert_contains_filter(collection, filter_name)
|
25
|
+
if collection.any? {|filter| filter.method == filter_name}
|
26
|
+
assert_block { true }
|
27
|
+
else
|
28
|
+
failure_msg = "#{filter_name.inspect} could not be found in #{collection.inspect}"
|
29
|
+
assert_block(failure_msg) { false }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def assert_filter_absent(collection, filter_name)
|
34
|
+
if collection.any? {|filter| filter.method == filter_name}
|
35
|
+
failure_msg = "#{filter_name.inspect} was unexpectedly found in #{collection.inspect}"
|
36
|
+
assert_block(failure_msg) { false }
|
37
|
+
else
|
38
|
+
assert_block { true }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def assert_chain_order(expected, chain)
|
43
|
+
chain_symbols = chain.map(&:method).map{ |f| f.is_a?(Proc) ? :a_proc : f.to_sym }
|
44
|
+
assert_equal expected, chain_symbols
|
45
|
+
end
|
metadata
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rails_inheritable_attributes_manager
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 19
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 3
|
9
|
+
- 0
|
10
|
+
version: 0.3.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Ryan L. Bell
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-08-07 00:00:00 -04:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
23
|
+
none: false
|
24
|
+
requirements:
|
25
|
+
- - "="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
hash: 35
|
28
|
+
segments:
|
29
|
+
- 2
|
30
|
+
- 10
|
31
|
+
- 2
|
32
|
+
version: 2.10.2
|
33
|
+
requirement: *id001
|
34
|
+
name: shoulda
|
35
|
+
prerelease: false
|
36
|
+
type: :development
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - "="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 27
|
44
|
+
segments:
|
45
|
+
- 1
|
46
|
+
- 2
|
47
|
+
- 2
|
48
|
+
version: 1.2.2
|
49
|
+
requirement: *id002
|
50
|
+
name: redgreen
|
51
|
+
prerelease: false
|
52
|
+
type: :development
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 3
|
60
|
+
segments:
|
61
|
+
- 2
|
62
|
+
- 3
|
63
|
+
- 0
|
64
|
+
version: 2.3.0
|
65
|
+
requirement: *id003
|
66
|
+
name: actionpack
|
67
|
+
prerelease: false
|
68
|
+
type: :development
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
hash: 3
|
76
|
+
segments:
|
77
|
+
- 2
|
78
|
+
- 3
|
79
|
+
- 0
|
80
|
+
version: 2.3.0
|
81
|
+
requirement: *id004
|
82
|
+
name: activerecord
|
83
|
+
prerelease: false
|
84
|
+
type: :development
|
85
|
+
description: Enhances Rails inheritable attributes to ensure that changes to super classes are passed on to the subclasses
|
86
|
+
email: ryan.l.bell@gmail.com
|
87
|
+
executables: []
|
88
|
+
|
89
|
+
extensions: []
|
90
|
+
|
91
|
+
extra_rdoc_files:
|
92
|
+
- LICENSE
|
93
|
+
- README.markdown
|
94
|
+
files:
|
95
|
+
- LICENSE
|
96
|
+
- README.markdown
|
97
|
+
- Rakefile
|
98
|
+
- VERSION
|
99
|
+
- RELEASE_NOTES
|
100
|
+
- Gemfile
|
101
|
+
- init.rb
|
102
|
+
- lib/models/nested_attributes.rb
|
103
|
+
- lib/controllers/controller_filters.rb
|
104
|
+
- lib/rails_inheritable_attributes_manager.rb
|
105
|
+
- tests/models/accepts_nested_attributes_for_test.rb
|
106
|
+
- tests/models/config.rb
|
107
|
+
- tests/test_helper.rb
|
108
|
+
- tests/controllers/normal_filter_chain_test.rb
|
109
|
+
- tests/controllers/append_before_test.rb
|
110
|
+
- tests/controllers/append_after_test.rb
|
111
|
+
- tests/controllers/skip_after_test.rb
|
112
|
+
- tests/controllers/prepend_after_test.rb
|
113
|
+
- tests/controllers/deep_class_hierarchy_test.rb
|
114
|
+
- tests/controllers/append_around_test.rb
|
115
|
+
- tests/controllers/prepend_before_test.rb
|
116
|
+
- tests/controllers/skip_test.rb
|
117
|
+
- tests/controllers/prepend_around_test.rb
|
118
|
+
- tests/controllers/skip_before_test.rb
|
119
|
+
has_rdoc: true
|
120
|
+
homepage: http://github.com/kofno/rails_inheritable_attributes_manager
|
121
|
+
licenses: []
|
122
|
+
|
123
|
+
post_install_message:
|
124
|
+
rdoc_options:
|
125
|
+
- --charset=UTF-8
|
126
|
+
require_paths:
|
127
|
+
- lib
|
128
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
hash: 3
|
134
|
+
segments:
|
135
|
+
- 0
|
136
|
+
version: "0"
|
137
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
|
+
none: false
|
139
|
+
requirements:
|
140
|
+
- - ">="
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
hash: 3
|
143
|
+
segments:
|
144
|
+
- 0
|
145
|
+
version: "0"
|
146
|
+
requirements: []
|
147
|
+
|
148
|
+
rubyforge_project:
|
149
|
+
rubygems_version: 1.3.7
|
150
|
+
signing_key:
|
151
|
+
specification_version: 3
|
152
|
+
summary: Manages inheritable attributes when super classes are re-opened
|
153
|
+
test_files: []
|
154
|
+
|