目前,我的模型和验证是这样的:
class Suya < ActiveRecord::Base
belongs_to :vendor
validates :meat, presence: true
validates_inclusion_of :spicy, :in => [true, false]
end
问题在于,当我运行此测试时:
test "suya is invalid if spiciness is not a boolean" do
suya = Suya.new(meat: "beef", spicy: 1)
suya1 = Suya.new(meat: "beef", spicy: "some string")
assert suya.invalid?
refute suya1.valid?
end
我收到了弃用警告:
弃权警告:您试图分配的值不是 显式
true
或false
到布尔列。目前这个价值 施放到false
。这将改变以匹配Ruby的语义,并且会 在Rails 5中转换为true
。
所以我认为我的验证并没有做我认为它应该做的事情。我认为我的验证检查列值是否存在,是否为IS或转换为true或false。所以我认为我的测试装置都转换为假,因此通过了我不想要的测试。我该怎么办?
答案 0 :(得分:1)
您可以使用自定义验证,如:
validate :check_boolean_field
def check_boolean_field
false unless self.spicy.is_a?(Boolean)
end
答案 1 :(得分:1)
每次为属性赋值时,Rails都会执行类型转换。这是一件方便的事情。这不是你的文本案例的错,它只是Rails的工作方式。如果属性是布尔值,它将转换看起来像真值的值(true
,1
,'1'
,'t'
,'T'
,'true'
,'TRUE'
,'on'
,'ON'
)至true
以及false
的任何其他内容。例如:
suya.spicy = "asdf"
suya.spicy # => false
# Likewise for other attribute types:
# Assuming Suya has an `id` attribute that is an Integer
suya.id = "asdf"
suya.id # => 0 # Because "asdf".to_i # => 0
# Assuming Suya has a `name` attribute that is a String
suya.name = 1
suya.name # => "1" # Because 1.to_s # => "1"
所以这就是rails的工作原理。在您的测试用例中,您的值通过质量分配被转换为各自属性的类型。
您可以通过为布尔值指定“某些值”来测试Rails的类型转换,或者您可以在测试用例中使用更明显的布尔值,如true
和false
。