用户应插入所有正值或负值。
我如何设置相同的符号验证?
对,我在before_save上写了这个..
unless (self.alt_1 >= 0 && self.alt_2 >=0 && self.alt_3 >= 0 &&
self.alt_4 >= 0 && self.alt_5 >= 0 && self.alt_6 >= 0) ||
(self.alt_1 <= 0 && self.alt_2 <=0 && self.alt_3 <= 0 &&
self.alt_4 <= 0 && self.alt_5 <= 0 && self.alt_6 <= 0)
self.errors.add_to_base(_("All values sign should be same."))
end
答案 0 :(得分:3)
first_sign = self.alt_1 <=> 0
(2..6).each do |n|
unless (self.send("alt_#{n}") <=> 0) == first_sign
errors.add_to_base(_("All values' signs should be same."))
break
end
end
使用此方法,我们首先获得alt_1的符号,然后查看其余元素(alt_2到alt_6)的符号是否匹配。一旦我们找到一个不匹配的,我们就添加验证错误并停止。它将运行最多6次迭代,最少2次。
另一个更聪明但效率更低的方法是使用方便的方法Enumerable#all?
,如果传递给它的块返回true,则返回true:
range = 1..6
errors.add_to_base(_("All values' signs should be same.")) unless
range.all? {|n| self.send("alt_#{n}") >= 0 } ||
range.all? {|n| self.send("alt_#{n}") <= 0 }
这里我们首先检查所有元素是否大于0,然后检查所有元素是否小于0.此方法最多迭代12次,最少6次。
答案 1 :(得分:1)
以下是一种略有不同的方法:
irb(main):020:0> def all_same_sign?(ary)
irb(main):021:1> ary.map { |x| x <=> 0 }.each_cons(2).all? { |x| x[0] == x[1] }
irb(main):022:1> end
=> nil
irb(main):023:0> all_same_sign? [1,2,3]
=> true
irb(main):024:0> all_same_sign? [1,2,0]
=> false
irb(main):025:0> all_same_sign? [-1, -5]
=> true
我们使用the spaceship operator来获取每个数字的符号,并确保每个元素与其后面的元素具有相同的符号。您还可以通过执行
将其重写为更懒惰ary.each_cons(2).all? { |x| (x[0] <=> 0) == (x[1] <=> 0) }
但在我看来这不太可读。
答案 2 :(得分:0)
unless
[:<=, :>=].any? do |check|
# Check either <= or >= for all values
[self.alt1, self.alt2, self.alt3, self.alt4, self.alt5, self.alt6].all? do |v|
v.send(check, 0)
end
end
self.errors.add_to_base(_("All values sign should be same."))
end