@@ -32,7 +32,7 @@ class RedundantPresenceValidationOnBelongsTo < Base
32
32
extend AutoCorrector
33
33
extend TargetRailsVersion
34
34
35
- MSG = 'Remove explicit presence validation for ` %<association>s` .'
35
+ MSG = 'Remove explicit presence validation for %<association>s.'
36
36
RESTRICT_ON_SEND = %i[ validates ] . freeze
37
37
38
38
minimum_target_rails_version 5.0
@@ -43,6 +43,9 @@ class RedundantPresenceValidationOnBelongsTo < Base
43
43
# @example source that matches - by association
44
44
# validates :user, presence: true
45
45
#
46
+ # @example source that matches - by association
47
+ # validates :name, :user, presence: true
48
+ #
46
49
# @example source that matches - with presence options
47
50
# validates :user, presence: { message: 'duplicate' }
48
51
#
@@ -51,8 +54,7 @@ class RedundantPresenceValidationOnBelongsTo < Base
51
54
def_node_matcher :presence_validation? , <<~PATTERN
52
55
$(
53
56
send nil? :validates
54
- (sym $_)
55
- ...
57
+ (sym $_)+
56
58
$(hash <$(pair (sym :presence) {true hash}) ...>)
57
59
)
58
60
PATTERN
@@ -150,22 +152,27 @@ class RedundantPresenceValidationOnBelongsTo < Base
150
152
PATTERN
151
153
152
154
def on_send ( node )
153
- validation , key , options , presence = presence_validation? ( node )
155
+ validation , all_keys , options , presence = presence_validation? ( node )
154
156
return unless validation
155
157
156
- belongs_to = belongs_to_for ( node . parent , key )
157
- return unless belongs_to
158
- return if optional? ( belongs_to )
159
-
160
- message = format ( MSG , association : key . to_s )
158
+ keys = all_keys . select do | key |
159
+ belongs_to = belongs_to_for ( node . parent , key )
160
+ belongs_to && ! optional? ( belongs_to )
161
+ end
162
+ return if keys . none?
161
163
162
- add_offense ( presence , message : message ) do |corrector |
164
+ add_offense ( presence , message : message_for ( keys ) ) do |corrector |
163
165
remove_presence_validation ( corrector , node , options , presence )
164
166
end
165
167
end
166
168
167
169
private
168
170
171
+ def message_for ( keys )
172
+ display_keys = keys . map { |key | "`#{ key } `" } . join ( '/' )
173
+ format ( MSG , association : display_keys )
174
+ end
175
+
169
176
def belongs_to_for ( model_class_node , key )
170
177
if key . to_s . end_with? ( '_id' )
171
178
normalized_key = key . to_s . delete_suffix ( '_id' ) . to_sym
0 commit comments