consistency_fail 0.1.1 → 0.2.0
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.
data/README.md
CHANGED
@@ -21,8 +21,6 @@ database-level enforcement is lacking there as well.
|
|
21
21
|
|
22
22
|
## Limitations
|
23
23
|
|
24
|
-
Currently only Rails 2.x is supported. Rails 3 support is coming soon.
|
25
|
-
|
26
24
|
consistency\_fail depends on being able to find all your `ActiveRecord::Base`
|
27
25
|
subclasses with some `$LOAD_PATH` trickery. If any models are in a path either
|
28
26
|
not on your project's load path or in a path that doesn't include the word
|
@@ -42,6 +40,7 @@ or simply beam in happiness at your application's perfect record for
|
|
42
40
|
|
43
41
|
## Coming Soon
|
44
42
|
|
43
|
+
* Handling validates\_uniqueness\_of calls scoped to an association (not a column)
|
45
44
|
* Rails 3 support
|
46
45
|
* Super-fail mode that monkey-patches explosions into your naughty models
|
47
46
|
|
data/consistency_fail.gemspec
CHANGED
@@ -20,8 +20,7 @@ consistency_fail will find your missing unique indexes, so you can add them and
|
|
20
20
|
stop ignoring the C in ACID.
|
21
21
|
EOF
|
22
22
|
|
23
|
-
s.
|
24
|
-
s.add_development_dependency "activerecord", "~>2.3"
|
23
|
+
s.add_development_dependency "activerecord", "~>3.0"
|
25
24
|
s.add_development_dependency "rspec"
|
26
25
|
|
27
26
|
s.files = `git ls-files`.split("\n")
|
@@ -1,20 +1,21 @@
|
|
1
|
-
require 'validation_reflection'
|
2
1
|
require 'consistency_fail/index'
|
3
2
|
|
4
3
|
module ConsistencyFail
|
5
4
|
module Introspectors
|
6
5
|
class ValidatesUniquenessOf
|
7
6
|
def instances(model)
|
8
|
-
model.
|
9
|
-
v.
|
7
|
+
model.validators.select do |v|
|
8
|
+
v.class == ActiveRecord::Validations::UniquenessValidator
|
10
9
|
end
|
11
10
|
end
|
12
11
|
|
13
12
|
def desired_indexes(model)
|
14
13
|
instances(model).map do |v|
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
v.attributes.map do |attribute|
|
15
|
+
scoped_columns = v.options[:scope] || []
|
16
|
+
ConsistencyFail::Index.new(model.table_name, [attribute, *scoped_columns])
|
17
|
+
end
|
18
|
+
end.flatten
|
18
19
|
end
|
19
20
|
private :desired_indexes
|
20
21
|
|
@@ -9,23 +9,23 @@ describe ConsistencyFail::Introspectors::ValidatesUniquenessOf do
|
|
9
9
|
describe "instances of validates_uniqueness_of" do
|
10
10
|
it "finds none" do
|
11
11
|
model = fake_ar_model("User")
|
12
|
-
model.stub!(:
|
12
|
+
model.stub!(:validators).and_return([])
|
13
13
|
|
14
14
|
subject.instances(model).should == []
|
15
15
|
end
|
16
16
|
|
17
17
|
it "finds one" do
|
18
18
|
model = fake_ar_model("User")
|
19
|
-
validation = double("validation", :
|
20
|
-
model.stub!(:
|
19
|
+
validation = double("validation", :class => ActiveRecord::Validations::UniquenessValidator)
|
20
|
+
model.stub!(:validators).and_return([validation])
|
21
21
|
|
22
22
|
subject.instances(model).should == [validation]
|
23
23
|
end
|
24
24
|
|
25
25
|
it "finds other validations, but not uniqueness" do
|
26
26
|
model = fake_ar_model("User")
|
27
|
-
validation = double("validation", :
|
28
|
-
model.stub!(:
|
27
|
+
validation = double("validation", :class => ActiveModel::Validations::FormatValidator)
|
28
|
+
model.stub!(:validators).and_return([validation])
|
29
29
|
|
30
30
|
subject.instances(model).should == []
|
31
31
|
end
|
@@ -33,14 +33,14 @@ describe ConsistencyFail::Introspectors::ValidatesUniquenessOf do
|
|
33
33
|
|
34
34
|
describe "finding missing indexes" do
|
35
35
|
before do
|
36
|
-
@validation = double("validation", :
|
36
|
+
@validation = double("validation", :class => ActiveRecord::Validations::UniquenessValidator)
|
37
37
|
@model = fake_ar_model("User", :table_exists? => true,
|
38
38
|
:table_name => "users",
|
39
|
-
:
|
39
|
+
:validators => [@validation])
|
40
40
|
end
|
41
41
|
|
42
42
|
it "finds one" do
|
43
|
-
@validation.stub!(:
|
43
|
+
@validation.stub!(:attributes => [:email], :options => {})
|
44
44
|
@model.stub_chain(:connection, :indexes).with("users").and_return([])
|
45
45
|
|
46
46
|
indexes = subject.missing_indexes(@model)
|
@@ -48,23 +48,32 @@ describe ConsistencyFail::Introspectors::ValidatesUniquenessOf do
|
|
48
48
|
end
|
49
49
|
|
50
50
|
it "finds one where the validation has scoped columns" do
|
51
|
-
@validation.stub!(:
|
51
|
+
@validation.stub!(:attributes => [:city], :options => {:scope => [:email, :state]})
|
52
52
|
@model.stub_chain(:connection, :indexes).with("users").and_return([])
|
53
53
|
|
54
54
|
indexes = subject.missing_indexes(@model)
|
55
55
|
indexes.should == [ConsistencyFail::Index.new("users", ["city", "email", "state"])]
|
56
56
|
end
|
57
57
|
|
58
|
-
it "
|
59
|
-
@validation.stub!(:
|
58
|
+
it "leaves the columns in the given order" do
|
59
|
+
@validation.stub!(:attributes => [:email], :options => {:scope => [:city, :state]})
|
60
60
|
@model.stub_chain(:connection, :indexes).with("users").and_return([])
|
61
61
|
|
62
62
|
indexes = subject.missing_indexes(@model)
|
63
63
|
indexes.should == [ConsistencyFail::Index.new("users", ["email", "city", "state"])]
|
64
64
|
end
|
65
65
|
|
66
|
+
it "finds two where there are multiple attributes" do
|
67
|
+
@validation.stub!(:attributes => [:email, :name], :options => {:scope => [:city, :state]})
|
68
|
+
@model.stub_chain(:connection, :indexes).with("users").and_return([])
|
69
|
+
|
70
|
+
indexes = subject.missing_indexes(@model)
|
71
|
+
indexes.should == [ConsistencyFail::Index.new("users", ["email", "city", "state"]),
|
72
|
+
ConsistencyFail::Index.new("users", ["name", "city", "state"])]
|
73
|
+
end
|
74
|
+
|
66
75
|
it "finds none when they're already in place" do
|
67
|
-
@validation.stub!(:
|
76
|
+
@validation.stub!(:attributes => [:email], :options => {})
|
68
77
|
index = fake_index_on(["email"], :unique => true)
|
69
78
|
@model.stub_chain(:connection, :indexes).with("users").
|
70
79
|
and_return([index])
|
@@ -73,7 +82,7 @@ describe ConsistencyFail::Introspectors::ValidatesUniquenessOf do
|
|
73
82
|
end
|
74
83
|
|
75
84
|
it "finds none when indexes are there but in a different order" do
|
76
|
-
@validation.stub!(:
|
85
|
+
@validation.stub!(:attributes => [:email], :options => {:scope => [:city, :state]})
|
77
86
|
index = fake_index_on(["state", "email", "city"], :unique => true)
|
78
87
|
@model.stub_chain(:connection, :indexes).with("users").
|
79
88
|
and_return([index])
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: consistency_fail
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Colin Jones
|
@@ -15,44 +15,28 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-06-
|
18
|
+
date: 2011-06-10 00:00:00 -05:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
|
-
- !ruby/object:Gem::Dependency
|
22
|
-
name: validation_reflection
|
23
|
-
prerelease: false
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
|
-
requirements:
|
27
|
-
- - ~>
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
hash: 3
|
30
|
-
segments:
|
31
|
-
- 0
|
32
|
-
- 3
|
33
|
-
- 8
|
34
|
-
version: 0.3.8
|
35
|
-
type: :runtime
|
36
|
-
version_requirements: *id001
|
37
21
|
- !ruby/object:Gem::Dependency
|
38
22
|
name: activerecord
|
39
23
|
prerelease: false
|
40
|
-
requirement: &
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
41
25
|
none: false
|
42
26
|
requirements:
|
43
27
|
- - ~>
|
44
28
|
- !ruby/object:Gem::Version
|
45
|
-
hash:
|
29
|
+
hash: 7
|
46
30
|
segments:
|
47
|
-
- 2
|
48
31
|
- 3
|
49
|
-
|
32
|
+
- 0
|
33
|
+
version: "3.0"
|
50
34
|
type: :development
|
51
|
-
version_requirements: *
|
35
|
+
version_requirements: *id001
|
52
36
|
- !ruby/object:Gem::Dependency
|
53
37
|
name: rspec
|
54
38
|
prerelease: false
|
55
|
-
requirement: &
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
56
40
|
none: false
|
57
41
|
requirements:
|
58
42
|
- - ">="
|
@@ -62,7 +46,7 @@ dependencies:
|
|
62
46
|
- 0
|
63
47
|
version: "0"
|
64
48
|
type: :development
|
65
|
-
version_requirements: *
|
49
|
+
version_requirements: *id002
|
66
50
|
description: |
|
67
51
|
With more than one application server, validates_uniqueness_of becomes a lie.
|
68
52
|
Two app servers -> two requests -> two near-simultaneous uniqueness checks ->
|