Joe H
Joe H

Reputation: 178

Rails validate parameter combinations

I have a search form with many fields. Each field is a parameter for searching a very large database. These parameters are passed to a search object. Some combinations of parameters are valid, others are not (they put too heavy a load on the system). What is the best way to write validations for combinations of parameters? For example: You should be able to search by name and one other field, but not name alone. In some cases if you enter a value in one field, you cannot enter a value in others

Currently I have something like this in my search class.

SEARCHABLE_ATTRIBUTES = [:name, :city, :state, :phone, :invoice_number, :payment_amount, :payment_date, :current_balance]

validate: valid_combinations

def valid_combinations
  unless name.present? && (SEARCHABLE_ATTRIBUTES - [:name, :invoice_number]).select{|sa| send(sa).present?}.any?
    errors.add(:name, "can't be given alone.")
  end
  if name.present? && invoice_number.present?
    errors.add(:invoice_number, "can't be searched with name")
  end
end

My valid search param restrictions get more complex than this, but this is just an example. Is there a better way to do this? I'd like to avoid one big valid_combinations method.

Upvotes: 1

Views: 738

Answers (1)

Rafael Ramos Bravin
Rafael Ramos Bravin

Reputation: 660

You can pass a condition to the validation and it will run only if that condition returns true.

So you could create separated validation methods and use them like this:

validate :at_least_another_column, if: Proc.new{|record| record.name }

Or, if you create a condition method named name_present you could code it like this:

validate :at_least_another_column, if: :name_present 

To substitute your second condition you could use:absence and :message options. Looking like this:

validates :invoice_number, absence: true, if: :name_present , message: "can't be searched with name"

As you can see the code becomes much cleaner and understandable when using separated validations. But depending on how complex your conditions may be, it could be easier to create a giant validator method

There's a lot more about validations here

Upvotes: 1

Related Questions