foreign_key_validation 0.0.3 → 0.0.4

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,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 7af20d0ad7b99c870491e939cb66a117ef0f4def
4
- data.tar.gz: e7c83abbc241fbcfab820e58b46b00fa64632ce8
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZjczM2MxZDBjMGMyNzYxZDNiZTM1YTliYTZjOTg2MDk4MjcyY2UyNA==
5
+ data.tar.gz: !binary |-
6
+ MTljYzJiY2IwOWM5NzY5OTU0M2FkMzNhODRmNWM3NDYyYTY4MDEzYQ==
5
7
  SHA512:
6
- metadata.gz: 92ec77233357a8e66e4410364439e5de674ac84d3c6a5d7f43e96193798495287e9f43426a579f56e05560ee01e24a85a7e7f134262f2ac917620743e52f4a8a
7
- data.tar.gz: 08191da451eb213cd450d013fac17de97eb433b5a9984c3358e406df51a75bf141da22c400995a689f3c27705dfe65d604a0e74b39f062841ce8febfc4334822
8
+ metadata.gz: !binary |-
9
+ Mjc0OTVlOGUyZWFkOTQ3ODE0OGFkNjJjZTMxMDdjYjc5ODhhMDA0NTFkZTE5
10
+ OGUxODgwNTRlYTAxM2ViNDRkZDMyZmYzNzMzMGVkZWFlMGZmOTY5OGQyM2Ji
11
+ ZWY4ZDU2NWM2MWNmMDJmY2MzMGQ2OWMzYjE0OGE5NDE0YjU2N2Q=
12
+ data.tar.gz: !binary |-
13
+ NmE5NzEyODJlNGMzNmVkYWI2ZDAwMTFiYTRkODMyZWExYzc2YWE0ZDVlYzEw
14
+ MzRiZGFkMzY3MzQxN2Y3ODg4ZDg5MmM5OWI3OGM0MjAwMDM3ZWEyZGM3N2Qw
15
+ M2IzM2E0ZDg0NmZhMDQyMGIwZWUxYjdkOTIwYjI0MmQwODVkYzA=
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.1.2
1
+ 1.9.3
data/README.md CHANGED
@@ -3,7 +3,9 @@
3
3
  Protect your models by specifying a collection of foreign keys that should be tested for consistency with the `belongs_to` relations. For example, when the `user_id` is used in all models we can check if the `user_id` of `model a` matches `user_id` of `model b` before saving the records.
4
4
 
5
5
  ## Requirements
6
- rails >= 3.2
6
+ ruby >= 1.9
7
+ rails
8
+ active_record
7
9
 
8
10
  ## Installation
9
11
 
@@ -21,22 +23,21 @@ Or install it yourself as:
21
23
 
22
24
  ## Usage
23
25
 
24
- Call `validate_foreign_keys` in your model. By default it assumes that it should check all foreign keys against the `user_id` column. So any relation accessed by `*_id` columns (except `user_id`) would be checked for a matching `user_id` (if the column exists).
26
+ Call `validate_foreign_keys` in your model. By default it assumes that it should check all foreign keys against the `user_id` column. So any relation (except `user`) will be checked for a matching `user_id` if the column exists.
25
27
 
26
28
  Change behaviour by calling `validate_foreign_keys` with arguments hash.
27
29
 
28
- validate_foreign_keys on: :admin_user_id, with: [:project_id]
30
+ validate_foreign_keys on: :admin_user, with: [:project]
29
31
 
30
32
  This would only check `model.project.admin_user_id` to match `model.admin_user_id`.
31
33
 
32
34
  ## Note
33
35
 
34
- Only tested with ruby 2.x and ActiveRecord
36
+ Only tested with ActiveRecord
35
37
 
36
38
  ## TODO
37
39
 
38
40
  - Tests!
39
- - Support Ruby 1.9 (remove keyword arguments)
40
41
 
41
42
  ## Contributing
42
43
 
@@ -4,41 +4,30 @@ module ForeignKeyValidation
4
4
 
5
5
  included do
6
6
  private
7
- def validate_foreign_key(key_to_validate_against, validation_key)
8
- relation = validation_key.gsub('_id', '')
9
-
10
- # do not try to validate if self does not respond to relation or one of the keys is nil
11
- return if !respond_to?(relation) or send(relation).try(key_to_validate_against).nil? or send(key_to_validate_against).nil?
12
-
13
- # add error if keys does not match
14
- if send(relation).send(key_to_validate_against) != send(key_to_validate_against)
15
- errors.add(key_to_validate_against, "#{key_to_validate_against} of #{relation} does not match #{self.class.name.tableize} #{key_to_validate_against}")
7
+ def validate_foreign_key(validate_against, relation)
8
+ if send(relation).send("#{validate_against}_id") != send("#{validate_against}_id")
9
+ errors.add(validate_against, "#{validate_against} of #{relation} does not match #{self.class.name.tableize} #{validate_against}")
16
10
  end
17
11
  end
18
12
  end
19
13
 
20
14
  module ClassMethods
21
- def validate_foreign_keys(on: :user_id, with: nil)
22
- key_to_validate_against = on.to_s
23
-
24
- # check if key_to_validate_against is present as column
25
- raise ArgumentError, "No foreign key #{key_to_validate_against} on #{self.table_name} table!" unless self.column_names.include?(key_to_validate_against)
26
-
27
- # use provided 'with' array or column_names from self to get all foreign keys
28
- keys_to_validate_with = (Array(with).map(&:to_s) if with) || self.column_names.select {|n| n.match(/\w_id/)}
15
+ def validate_foreign_keys(opt={})
16
+ validate_against = (opt[:on] || :user).to_s
17
+ reflections = self.reflect_on_all_associations(:belongs_to).map(&:name).map(&:to_s)
18
+ validate_with = ((Array(opt[:with]).map(&:to_s) if opt[:with]) || reflections).reject {|n| n == validate_against}
29
19
 
30
- # reject keys that match either the key_to_validate_against or the current class name key (needed for sti models)
31
- keys_to_validate_with.reject! {|n| n == key_to_validate_against || n == "#{self.class.name.underscore}_id" }
20
+ raise ArgumentError, "No foreign key #{validate_against} on #{self.table_name} table!" unless reflections.include?(validate_against)
21
+ raise ArgumentError, "Unknown relation in #{validate_with}!" unless validate_with.all? {|k| reflections.include?(k) }
32
22
 
33
- define_method "validate_foreign_keys_on_#{key_to_validate_against}" do
34
- keys_to_validate_with.each do |validation_key|
35
- validate_foreign_key(key_to_validate_against, validation_key)
23
+ define_method "validate_foreign_keys_on_#{validate_against}" do
24
+ validate_with.each do |relation|
25
+ validate_foreign_key(validate_against, relation)
36
26
  end
37
27
  end
38
- private "validate_foreign_keys_on_#{key_to_validate_against}".to_sym
28
+ private "validate_foreign_keys_on_#{validate_against}".to_sym
39
29
 
40
- # add before filter to validate key
41
- before_validation "validate_foreign_keys_on_#{key_to_validate_against}"
30
+ before_validation "validate_foreign_keys_on_#{validate_against}"
42
31
  end
43
32
  end
44
33
  end
@@ -1,3 +1,3 @@
1
1
  module ForeignKeyValidation
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -71,21 +71,21 @@ describe ForeignKeyValidation::ModelExtension do
71
71
  it "does not allow to rewrite user id of idea" do
72
72
  idea.user_id = 42
73
73
  idea.save
74
- expect(idea.errors.messages.values.flatten).to include("user_id of project does not match ideas user_id")
74
+ expect(idea.errors.messages.values.flatten).to include("user of project does not match ideas user")
75
75
  expect(idea.reload.user_id).to_not eq(42)
76
76
  end
77
77
 
78
78
  it "does not allow to rewrite user id of issue" do
79
79
  issue.user_id = 42
80
80
  issue.save
81
- expect(issue.errors.messages.values.flatten).to include("user_id of project does not match issues user_id")
81
+ expect(issue.errors.messages.values.flatten).to include("user of project does not match issues user")
82
82
  expect(issue.reload.user_id).to_not eq(42)
83
83
  end
84
84
 
85
85
  it "does not allow to rewrite user id of comment" do
86
86
  comment.user_id = 42
87
87
  comment.save
88
- expect(comment.errors.messages.values.flatten).to include("user_id of issue does not match comments user_id")
88
+ expect(comment.errors.messages.values.flatten).to include("user of issue does not match comments user")
89
89
  expect(comment.reload.user_id).to_not eq(42)
90
90
  end
91
91
 
@@ -101,34 +101,78 @@ describe ForeignKeyValidation::ModelExtension do
101
101
  end
102
102
 
103
103
  it "does not allow to call private validate_foreign_keys_on_* methods" do
104
- expect{issue.validate_foreign_keys_on_user_id}.to raise_exception(/private method `validate_foreign_keys_on_user_id' called/)
104
+ expect{issue.validate_foreign_keys_on_user}.to raise_exception(/private method `validate_foreign_keys_on_user' called/)
105
105
  end
106
106
 
107
107
  end
108
108
 
109
- context "With calling validation with wrong attributes hash" do
109
+ context "With calling validation with attributes hash" do
110
+ before do
111
+ Idea.class_eval do
112
+ validate_foreign_keys on: :user, with: :project
113
+ end
114
+ end
110
115
 
111
116
  # NOTE: it's important here to not create the object through relation (user.projects.create...)
112
117
  # it looks like active_record is caching the classes - but we need to test different class configs
113
118
  let(:user) { User.create }
114
119
  let(:project) { Project.create user: user }
120
+ let(:idea) { Idea.create user: user, project: project }
115
121
  let(:issue) { Issue.create user: user, project: project }
116
122
  let(:comment) { Comment.create user: user, issue: issue }
117
123
 
118
- it "raises error due to wrong :on key" do
119
- expect{Idea.class_eval { validate_foreign_keys on: :not_existing_id }}.to raise_error("No foreign key not_existing_id on ideas table!")
124
+ it "uses same user ids by default" do
125
+ expect(project.user_id).to eq(user.id)
126
+ expect(idea.user_id).to eq(user.id)
120
127
  end
121
128
 
122
- it "does not validate due to wrong :with key" do
123
- Issue.class_eval do
124
- validate_foreign_keys with: :not_existing_id
125
- end
129
+ it "does not allow to rewrite user id of idea" do
130
+ idea.user_id = 42
131
+ idea.save
132
+ expect(idea.errors.messages.values.flatten).to include("user of project does not match ideas user")
133
+ expect(idea.reload.user_id).to_not eq(42)
134
+ end
135
+
136
+ it "allow to rewrite user id of project" do
137
+ project.user_id = 42
138
+ project.save
139
+ project.reload
140
+ expect(project.user_id).to eq(42)
141
+ end
142
+
143
+ it "allow to rewrite user id of issue" do
126
144
  issue.user_id = 42
127
145
  issue.save
128
146
  issue.reload
129
147
  expect(issue.user_id).to eq(42)
130
148
  end
131
149
 
150
+ it "allow to rewrite user id of comment" do
151
+ comment.user_id = 42
152
+ comment.save
153
+ comment.reload
154
+ expect(comment.user_id).to eq(42)
155
+ end
156
+
157
+ end
158
+
159
+ context "With calling validation with wrong attributes hash" do
160
+
161
+ # NOTE: it's important here to not create the object through relation (user.projects.create...)
162
+ # it looks like active_record is caching the classes - but we need to test different class configs
163
+ let(:user) { User.create }
164
+ let(:project) { Project.create user: user }
165
+ let(:issue) { Issue.create user: user, project: project }
166
+ let(:comment) { Comment.create user: user, issue: issue }
167
+
168
+ it "raises error due to wrong :on key" do
169
+ expect{Idea.class_eval { validate_foreign_keys on: :not_existing_id }}.to raise_error("No foreign key not_existing_id on ideas table!")
170
+ end
171
+
172
+ it "raises error due to wrong :with key" do
173
+ expect{Idea.class_eval { validate_foreign_keys with: :not_existing_id }}.to raise_error('Unknown relation in ["not_existing_id"]!')
174
+ end
175
+
132
176
  end
133
177
 
134
178
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreign_key_validation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marcus Geißler
@@ -14,84 +14,84 @@ dependencies:
14
14
  name: rails
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ~>
18
18
  - !ruby/object:Gem::Version
19
19
  version: 4.0.0
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ~>
25
25
  - !ruby/object:Gem::Version
26
26
  version: 4.0.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ~>
32
32
  - !ruby/object:Gem::Version
33
33
  version: '1.6'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ~>
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.6'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ~>
46
46
  - !ruby/object:Gem::Version
47
47
  version: '10.1'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ~>
53
53
  - !ruby/object:Gem::Version
54
54
  version: '10.1'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec-rails
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ~>
60
60
  - !ruby/object:Gem::Version
61
61
  version: '3.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ~>
67
67
  - !ruby/object:Gem::Version
68
68
  version: '3.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: sqlite3
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ~>
74
74
  - !ruby/object:Gem::Version
75
75
  version: '1.3'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ~>
81
81
  - !ruby/object:Gem::Version
82
82
  version: '1.3'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: pry
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - "~>"
87
+ - - ~>
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0.10'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - "~>"
94
+ - - ~>
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0.10'
97
97
  description: Protect the foreign keys in your Rails models. Really.
@@ -101,10 +101,10 @@ executables: []
101
101
  extensions: []
102
102
  extra_rdoc_files: []
103
103
  files:
104
- - ".gitignore"
105
- - ".rspec"
106
- - ".ruby-gemset"
107
- - ".ruby-version"
104
+ - .gitignore
105
+ - .rspec
106
+ - .ruby-gemset
107
+ - .ruby-version
108
108
  - Gemfile
109
109
  - LICENSE
110
110
  - README.md
@@ -128,12 +128,12 @@ require_paths:
128
128
  - lib
129
129
  required_ruby_version: !ruby/object:Gem::Requirement
130
130
  requirements:
131
- - - ">="
131
+ - - ! '>='
132
132
  - !ruby/object:Gem::Version
133
133
  version: '0'
134
134
  required_rubygems_version: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - ">="
136
+ - - ! '>='
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
139
  requirements: []