Skip to content

Commit 0952552

Browse files
committed
Deprecate passing string to :if and :unless conditional options on set_callback and skip_callback
1 parent f8d3fed commit 0952552

File tree

5 files changed

+68
-14
lines changed

5 files changed

+68
-14
lines changed

activemodel/test/cases/validations/conditional_validation_test.rb

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ def test_unless_validation_using_method_false
4343

4444
def test_if_validation_using_string_true
4545
# When the evaluated string returns true
46-
Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", if: "a = 1; a == 1")
46+
ActiveSupport::Deprecation.silence do
47+
Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", if: "a = 1; a == 1")
48+
end
4749
t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
4850
assert t.invalid?
4951
assert t.errors[:title].any?
@@ -52,23 +54,29 @@ def test_if_validation_using_string_true
5254

5355
def test_unless_validation_using_string_true
5456
# When the evaluated string returns true
55-
Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", unless: "a = 1; a == 1")
57+
ActiveSupport::Deprecation.silence do
58+
Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", unless: "a = 1; a == 1")
59+
end
5660
t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
5761
assert t.valid?
5862
assert_empty t.errors[:title]
5963
end
6064

6165
def test_if_validation_using_string_false
6266
# When the evaluated string returns false
63-
Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", if: "false")
67+
ActiveSupport::Deprecation.silence do
68+
Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", if: "false")
69+
end
6470
t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
6571
assert t.valid?
6672
assert_empty t.errors[:title]
6773
end
6874

6975
def test_unless_validation_using_string_false
7076
# When the evaluated string returns false
71-
Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", unless: "false")
77+
ActiveSupport::Deprecation.silence do
78+
Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", unless: "false")
79+
end
7280
t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
7381
assert t.invalid?
7482
assert t.errors[:title].any?
@@ -118,7 +126,9 @@ def test_unless_validation_using_block_false
118126
# ensure that it works correctly
119127
def test_validation_with_if_as_string
120128
Topic.validates_presence_of(:title)
121-
Topic.validates_presence_of(:author_name, if: "title.to_s.match('important')")
129+
ActiveSupport::Deprecation.silence do
130+
Topic.validates_presence_of(:author_name, if: "title.to_s.match('important')")
131+
end
122132

123133
t = Topic.new
124134
assert t.invalid?, "A topic without a title should not be valid"

activemodel/test/cases/validations/with_validation_test.rb

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,26 +69,34 @@ def check_validity!
6969
end
7070

7171
test "with if statements that return false" do
72-
Topic.validates_with(ValidatorThatAddsErrors, if: "1 == 2")
72+
ActiveSupport::Deprecation.silence do
73+
Topic.validates_with(ValidatorThatAddsErrors, if: "1 == 2")
74+
end
7375
topic = Topic.new
7476
assert topic.valid?
7577
end
7678

7779
test "with if statements that return true" do
78-
Topic.validates_with(ValidatorThatAddsErrors, if: "1 == 1")
80+
ActiveSupport::Deprecation.silence do
81+
Topic.validates_with(ValidatorThatAddsErrors, if: "1 == 1")
82+
end
7983
topic = Topic.new
8084
assert topic.invalid?
8185
assert_includes topic.errors[:base], ERROR_MESSAGE
8286
end
8387

8488
test "with unless statements that return true" do
85-
Topic.validates_with(ValidatorThatAddsErrors, unless: "1 == 1")
89+
ActiveSupport::Deprecation.silence do
90+
Topic.validates_with(ValidatorThatAddsErrors, unless: "1 == 1")
91+
end
8692
topic = Topic.new
8793
assert topic.valid?
8894
end
8995

9096
test "with unless statements that returns false" do
91-
Topic.validates_with(ValidatorThatAddsErrors, unless: "1 == 2")
97+
ActiveSupport::Deprecation.silence do
98+
Topic.validates_with(ValidatorThatAddsErrors, unless: "1 == 2")
99+
end
92100
topic = Topic.new
93101
assert topic.invalid?
94102
assert_includes topic.errors[:base], ERROR_MESSAGE
@@ -102,7 +110,9 @@ def check_validity!
102110
validator.expect(:is_a?, false, [Symbol])
103111
validator.expect(:is_a?, false, [String])
104112

105-
Topic.validates_with(validator, if: "1 == 1", foo: :bar)
113+
ActiveSupport::Deprecation.silence do
114+
Topic.validates_with(validator, if: "1 == 1", foo: :bar)
115+
end
106116
assert topic.valid?
107117
validator.verify
108118
end

activesupport/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
* Deprecate passing string to `:if` and `:unless` conditional options
2+
on `set_callback` and `skip_callback`.
3+
4+
*Ryuta Kamizono*
5+
16
* Raise `ArgumentError` when passing string to define callback.
27

38
*Ryuta Kamizono*

activesupport/lib/active_support/callbacks.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,14 @@ def __update_callbacks(name) #:nodoc:
667667
# existing chain rather than appended.
668668
def set_callback(name, *filter_list, &block)
669669
type, filters, options = normalize_callback_params(filter_list, block)
670+
671+
if options[:if].is_a?(String) || options[:unless].is_a?(String)
672+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
673+
Passing string to :if and :unless conditional options is deprecated
674+
and will be removed in Rails 5.2 without replacement.
675+
MSG
676+
end
677+
670678
self_chain = get_callbacks name
671679
mapped = filters.map do |filter|
672680
Callback.build(self_chain, filter, type, options)
@@ -690,6 +698,14 @@ def set_callback(name, *filter_list, &block)
690698
# already been set (unless the <tt>:raise</tt> option is set to <tt>false</tt>).
691699
def skip_callback(name, *filter_list, &block)
692700
type, filters, options = normalize_callback_params(filter_list, block)
701+
702+
if options[:if].is_a?(String) || options[:unless].is_a?(String)
703+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
704+
Passing string to :if and :unless conditional options is deprecated
705+
and will be removed in Rails 5.2 without replacement.
706+
MSG
707+
end
708+
693709
options[:raise] = true unless options.key?(:raise)
694710

695711
__update_callbacks(name) do |target, chain|

activesupport/test/callbacks_test.rb

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,10 +192,12 @@ class ConditionalPerson < Record
192192
before_save Proc.new { |r| r.history << [:before_save, :symbol] }, unless: :no
193193
before_save Proc.new { |r| r.history << "b00m" }, unless: :yes
194194
# string
195-
before_save Proc.new { |r| r.history << [:before_save, :string] }, if: "yes"
196-
before_save Proc.new { |r| r.history << "b00m" }, if: "no"
197-
before_save Proc.new { |r| r.history << [:before_save, :string] }, unless: "no"
198-
before_save Proc.new { |r| r.history << "b00m" }, unless: "yes"
195+
ActiveSupport::Deprecation.silence do
196+
before_save Proc.new { |r| r.history << [:before_save, :string] }, if: "yes"
197+
before_save Proc.new { |r| r.history << "b00m" }, if: "no"
198+
before_save Proc.new { |r| r.history << [:before_save, :string] }, unless: "no"
199+
before_save Proc.new { |r| r.history << "b00m" }, unless: "yes"
200+
end
199201
# Combined if and unless
200202
before_save Proc.new { |r| r.history << [:before_save, :combined_symbol] }, if: :yes, unless: :no
201203
before_save Proc.new { |r| r.history << "b00m" }, if: :yes, unless: :yes
@@ -1204,6 +1206,17 @@ def test_skip_without_raise # removes nothing
12041206
end
12051207
end
12061208

1209+
class DeprecatedWarningTest < ActiveSupport::TestCase
1210+
def test_deprecate_string_conditional_options
1211+
klass = Class.new(Record)
1212+
1213+
assert_deprecated { klass.before_save :tweedle, if: "true" }
1214+
assert_deprecated { klass.after_save :tweedle, unless: "false" }
1215+
assert_deprecated { klass.skip_callback :save, :before, :tweedle, if: "true" }
1216+
assert_deprecated { klass.skip_callback :save, :after, :tweedle, unless: "false" }
1217+
end
1218+
end
1219+
12071220
class NotPermittedStringCallbackTest < ActiveSupport::TestCase
12081221
def test_passing_string_callback_is_not_permitted
12091222
klass = Class.new(Record)

0 commit comments

Comments
 (0)