Skip to content

Commit c23478a

Browse files
authored
Merge pull request #882 from etiennebarrie/uniqueness-with-conditions
Fix false positive in UniquenessValidator with `conditions`
2 parents 2775559 + 61d3f6c commit c23478a

File tree

3 files changed

+41
-13
lines changed

3 files changed

+41
-13
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* [#882](https://github.com/rubocop/rubocop-rails/pull/882): Fix false positive for `Rails/UniqueValidationWithoutIndex` with :conditions option. ([@etiennebarrie][])

lib/rubocop/cop/rails/unique_validation_without_index.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,20 @@ def condition_part?(node)
139139
pairs = node.arguments.last
140140
return unless pairs.hash_type?
141141

142+
return true if condition_hash_part?(pairs, keys: %i[if unless])
143+
144+
uniqueness_node = uniqueness_part(node)
145+
return unless uniqueness_node&.hash_type?
146+
147+
condition_hash_part?(uniqueness_node, keys: %i[if unless conditions])
148+
end
149+
150+
def condition_hash_part?(pairs, keys:)
142151
pairs.each_pair.any? do |pair|
143152
key = pair.key
144153
next unless key.sym_type?
145154

146-
key.value == :if || key.value == :unless
155+
keys.include?(key.value)
147156
end
148157
end
149158

spec/rubocop/cop/rails/unique_validation_without_index_spec.rb

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ class Article
327327
end
328328
end
329329

330-
context 'with an if condition on the validation' do
330+
context 'without the proper index' do
331331
let(:schema) { <<~RUBY }
332332
ActiveRecord::Schema.define(version: 2020_02_02_075409) do
333333
create_table "articles", force: :cascade do |t|
@@ -336,30 +336,48 @@ class Article
336336
end
337337
RUBY
338338

339-
it 'does not register an offense' do
339+
it 'does not register an offense with an if condition on validates' do
340340
expect_no_offenses(<<~RUBY)
341341
class Article
342342
belongs_to :user
343343
validates :user, uniqueness: true, if: -> { false }
344344
end
345345
RUBY
346346
end
347-
end
348347

349-
context 'with an unless condition on the validation' do
350-
let(:schema) { <<~RUBY }
351-
ActiveRecord::Schema.define(version: 2020_02_02_075409) do
352-
create_table "articles", force: :cascade do |t|
353-
t.bigint "user_id", null: false
348+
it 'does not register an offense with an unless condition on validates' do
349+
expect_no_offenses(<<~RUBY)
350+
class Article
351+
belongs_to :user
352+
validates :user, uniqueness: true, unless: -> { true }
354353
end
355-
end
356-
RUBY
354+
RUBY
355+
end
357356

358-
it 'does not register an offense' do
357+
it 'does not register an offense with an if condition on the specific validator' do
359358
expect_no_offenses(<<~RUBY)
360359
class Article
361360
belongs_to :user
362-
validates :user, uniqueness: true, unless: -> { true }
361+
validates :user, uniqueness: { if: -> { false } }
362+
end
363+
RUBY
364+
end
365+
366+
it 'does not register an offense with an unless condition on the specific validator' do
367+
expect_no_offenses(<<~RUBY)
368+
class Article
369+
belongs_to :user
370+
validates :user, uniqueness: { unless: -> { false } }
371+
end
372+
RUBY
373+
end
374+
375+
it 'does not register an offense with a conditions option on the specific validator' do
376+
expect_no_offenses(<<~RUBY)
377+
class Article
378+
belongs_to :user
379+
enum :status, [:draft, :published]
380+
validates :user, uniqueness: { conditions: -> { published } }
363381
end
364382
RUBY
365383
end

0 commit comments

Comments
 (0)