我正在编写一些代码来评估一堆字符串的存在,我想确保只有1存在。它们是相互排斥的。
class MyClass
include ActiveModel::Validations
attr_accessor :a, :b, :c
validate :mutex_values
def initialize(attr = {})
attr.each do |k, v|
send("#{k}=", v)
end
end
private
def mutex_values
# here, I want to do this:
# errors.add(:base, "specify only 1") unless a ^ b ^ c
# instead I do this
errors.add(:base, "specify only 1") unless a.present? ^ b.present? ^ c.present?
end
end
MyClass.new(:a => "A", :b => "B", :c => "C").valid?
=> false
是否有其他方法不需要重复使用.present?
? Monkey patch用于定义运算符^
的字符串?我只是习惯于能够做if a
,因为需要基本上对布尔值的显式转换感觉不自然。我觉得这个用例会在Ruby中“正常工作”。
答案 0 :(得分:2)
您可以使用count
执行此类操作:
errors.add(:base 'specify exactly 1') unless [a, b, c].count(&:present?) == 1
如果您最多想要一个而不是一个,那么:
errors.add(:base 'specify at most 1') unless [a, b, c].count(&:present?) > 1
例如:
> ['',nil,'6',''].count(&:present?)
=> 1
> ['',nil,'6',11].count(&:present?)
=> 2
> ['',nil,''].count(&:present?)
=> 0
答案 1 :(得分:2)
Enumerable实际上定义了一个one?
方法,它完全符合您的需要。
# So either...
[a, b, c].one?(&:present?)
# or
[a, b, c].one?(&:presence)
# ... would do the trick in this case.
不幸的是,如果你想要two?
或etcera,那你就不走运了。
答案 2 :(得分:1)
如果您想检查方法a
,b
和c
中是否只有一个返回非空值,您可以使用:
[a, b, c].compact.count == 1
或者甚至,多亏了数字,
[a, b, c].one?