1
\$\begingroup\$

I have four fields a, b, c, and d. All of them must be populated if any of them have a value.

So what I want to do is validate that they are all populated, if any of them have a value. I'm trying to determine the best way to do this. I think I could do this:

  class User < ActiveRecord::Base
    validates_presence_of :a, :b, :c, :if => lambda { self.d.present? }
    validates_presence_of :b, :c, :d, :if => lambda { self.a.present? }
    validates_presence_of :a, :c, :d, :if => lambda { self.b.present? }
    validates_presence_of :a, :b, :d, :if => lambda { self.c.present? }
  end
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Can someone explain why this is off topic? It's not pseudocode, hypothetical, or stub code. Nor is it someone else's code. This code functions, and I just wanted to see if anyone had suggestions to make it more efficient. My understanding is that is what Code Review is for as opposed to posting this on Stack Overflow. Added the class and end lines so it was the complete RoR model. \$\endgroup\$ Commented Dec 12, 2015 at 22:29
  • \$\begingroup\$ Do you really use a, b, c and d in your actual code? What is the meaning behind those fields? \$\endgroup\$ Commented Dec 12, 2015 at 23:32

1 Answer 1

2
\$\begingroup\$

I noticed that you use 'hard' and repeated parts of code. My way to solve this task is to write a custom validation (I try to avoid them but sometimes there no other choice).

I try to place custom validations in a separate file (in config\initializers\ directory).

ActiveRecord::Base.class_eval do
  def self.validates_dependent_fields(*attr_names)
    fields_count = 0
    attr_names.each{ |attribute| fields_count += 1 if record[attribute] }

    validates_each(attr_names) do |record, attribute, value|
      if value && fields_count < attr_names.length
        record.errors[attribute] << "Dependent fields can not be empty."
      end
    end

  end
end

Algorithm:

  1. Get the number of not nil fields;
  2. Validate each field (and add error message if the attribute value is not nil and one or more dependent fields are not present).

Then, in the model:

class SomeModel < ActiveRecord::Base
  validates_dependent_fields :a, :b, :c, :d
end

Note that you can reuse this validation in any other model.

P.S.: I've not tested this code yet.

\$\endgroup\$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.