Module: HasHelpers::ActiveRecord::Validation

Defined in:
lib/has_helpers/active_record/validation.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.scopes_one_or_more(*args) ⇒ Object

Adds validations to require at least on of the given attributes.

Examples

scopes_one_or_more :product_class, :product_type, :product_category



51
52
53
54
55
56
57
58
59
60
# File 'lib/has_helpers/active_record/validation.rb', line 51

def self.scopes_one_or_more(*args)
  options = args.extract_options!
  validate do
    unless args.any? { |attr| send(attr) } # Check that at least one of the attributes is set
      Array(options[:attribute] || args).each do |attr|
        errors[attr] << "Must set one of " + args.map { |arg| arg.to_s.humanize }.to_sentence(last_word_connector: " or ")
      end
    end
  end
end

Instance Method Details

#scopes_xor(*args) ⇒ Object

Options

[:attribute] When given an accessor reader method will be created with the given name. Also, errors will be assigned to this attribute instead of those passed in the arguments.

[:allow_none] When this option is set, then the presence of one of the given attributes is not required.

Examples

scopes_xor :amount, :percent socpes_xor :advisor_id, :user_id, :firm_id, :company_id, :attribute => :owner



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/has_helpers/active_record/validation.rb', line 18

def scopes_xor(*args)
  options = args.extract_options!

  # Add validation to ensure that exactly one of the given attributes is set.
  validate do
    number_of_attrs_set = args.sum { |arg| send(arg) ? 1 : 0 }
    if number_of_attrs_set == 0 && !options[:allow_none]
      Array(options[:attribute] || args).each do |attr|
        errors[attr] << "Must be assigned one of " + args.map { |arg| arg.to_s.humanize }.to_sentence(last_word_connector: " or ")
      end
    elsif number_of_attrs_set > 1
      Array(options[:attribute] || args).each do |attr|
        errors[attr] << "May be assigned to only one of " + args.map { |arg| arg.to_s.humanize }.to_sentence(last_word_connector: " or ")
      end
    end
  end

  # Create a accessor reader method for the given attribute name (if any).
  if options[:attribute]
    define_method(options[:attribute]) do
      args.lazy.map { |attr| send(attr.to_s.remove(/_id$/)) }.detect(&:identity)
    end

    # Returns the attribute name for the current owner, which may be a foreign_key for belongs_to associations, e.g. "advisor_id".
    define_method("#{ options[:attribute] }_attribute") do
      args.detect { |attr| send(attr) }
    end
  end
end