为什么我必须显式消除空白才能让 shoulda matcher `inclusion:` 验证通过?
Why do I have to explicitly nilify blanks for the shoulda matcher `inclusion:` validation to pass?
我的数据库中有一个包含时区的字符串列。有效值包括 nil
或 ActiveSupport 识别为时区的任何值
我使用 shoulda-matchers 为我的模型验证编写规范:
# app/models/my_model.rb
class MyModel < ApplicationRecord
validates :timezone, inclusion: ActiveSupport::TimeZone::MAPPING.keys, allow_nil: true
end
# spec/models/my_model_spec.rb
describe "timezone" do
it do
should validate_inclusion_of(:timezone).
in_array(ActiveSupport::TimeZone::MAPPING.keys).
allow_blank
end
end
它抛出了一个错误:
Failure/Error: it { should validate_inclusion_of(:timezone).in_array(ActiveSupport::TimeZone::MAPPING.keys).allow_blank }
MyModel did not properly validate that
:timezone is either ‹"International Date Line West"›, ‹"Midway Island"›,
‹"American Samoa"›, ‹"Hawaii"›, ‹"Alaska"›, ‹"Pacific Time (US &
.....
.....
.....
‹"Auckland"›, ‹"Wellington"›, ‹"Nuku'alofa"›, ‹"Tokelau Is."›, ‹"Chatham
Is."›, or ‹"Samoa"›, but only if it is not blank.
After setting :timezone to ‹""›, the matcher expected the
MyModel to be valid, but it was invalid
instead, producing these validation errors:
* timezone: ["is not included in the list"]
Shoulda matchers 将列设置为 ""
并期望验证应该通过。但为什么会这样呢? nil
是严格允许的,但不应该是空字符串值,对吧?
有没有我错过的更合适的设置方法?
为了解决这个问题,我使用了 before_validation
块。 (而且我知道 nilify_blanks gem 做同样的事情)。但是我不得不把它包括在内感觉很奇怪
before_validation do
self[:timezone] = nil if self[:timezone].blank?
end
.blank?
是一种 ActiveSupport 方法,对于 nil
、false
以及更重要的 ""
(空字符串),returns 为真。
这就是 allow_blank
使用空字符串进行测试的原因。请改用 allow_nil
。
# spec/models/my_model_spec.rb
describe "timezone" do
it do
should validate_inclusion_of(:timezone).
in_array(ActiveSupport::TimeZone::MAPPING.keys).
allow_nil
end
end
我的数据库中有一个包含时区的字符串列。有效值包括 nil
或 ActiveSupport 识别为时区的任何值
我使用 shoulda-matchers 为我的模型验证编写规范:
# app/models/my_model.rb
class MyModel < ApplicationRecord
validates :timezone, inclusion: ActiveSupport::TimeZone::MAPPING.keys, allow_nil: true
end
# spec/models/my_model_spec.rb
describe "timezone" do
it do
should validate_inclusion_of(:timezone).
in_array(ActiveSupport::TimeZone::MAPPING.keys).
allow_blank
end
end
它抛出了一个错误:
Failure/Error: it { should validate_inclusion_of(:timezone).in_array(ActiveSupport::TimeZone::MAPPING.keys).allow_blank }
MyModel did not properly validate that
:timezone is either ‹"International Date Line West"›, ‹"Midway Island"›,
‹"American Samoa"›, ‹"Hawaii"›, ‹"Alaska"›, ‹"Pacific Time (US &
.....
.....
.....
‹"Auckland"›, ‹"Wellington"›, ‹"Nuku'alofa"›, ‹"Tokelau Is."›, ‹"Chatham
Is."›, or ‹"Samoa"›, but only if it is not blank.
After setting :timezone to ‹""›, the matcher expected the
MyModel to be valid, but it was invalid
instead, producing these validation errors:
* timezone: ["is not included in the list"]
Shoulda matchers 将列设置为 ""
并期望验证应该通过。但为什么会这样呢? nil
是严格允许的,但不应该是空字符串值,对吧?
有没有我错过的更合适的设置方法?
为了解决这个问题,我使用了 before_validation
块。 (而且我知道 nilify_blanks gem 做同样的事情)。但是我不得不把它包括在内感觉很奇怪
before_validation do
self[:timezone] = nil if self[:timezone].blank?
end
.blank?
是一种 ActiveSupport 方法,对于 nil
、false
以及更重要的 ""
(空字符串),returns 为真。
这就是 allow_blank
使用空字符串进行测试的原因。请改用 allow_nil
。
# spec/models/my_model_spec.rb
describe "timezone" do
it do
should validate_inclusion_of(:timezone).
in_array(ActiveSupport::TimeZone::MAPPING.keys).
allow_nil
end
end