迅速で汚い解決策:
require 'active_model'
class Person
include ActiveModel::Validations
attr_accessor :aa, :bb
validate :only_one_present
def initialize(options = {})
self.aa = options[:aa]
self.bb = options[:bb]
end
private
def only_one_present
if both_present || no_attr_present
errors.add(:base, 'Invalid!')
end
end
def both_present
!aa.nil? && !aa.empty? && !bb.nil? && !bb.empty?
end
def no_attr_present
(aa.nil? || aa.empty?) && (bb.nil? || bb.empty?)
end
end
puts Person.new(aa: 'asad', bb: 'sdsd').valid? # => false
puts Person.new(aa: nil, bb: 'sdsd').valid? # => true
puts Person.new(aa: 'asad', bb: nil).valid? # => true
puts Person.new(aa: nil, bb: nil).valid? # => false
もちろん、最初に適切な仕様を作成する必要があり、そのためのバリデータ クラスを抽出できます。
編集:
またはActiveSupport を使用している場合は、変更nil?
およびempty?
組み合わせが可能です。present?
blank?