Michael Discenza
Michael Discenza

Reputation: 3330

Running rails inclusion validation only if presence passes

I want to have validate the presence of a field first and return one error message if there is no value for the field. Then assuming that this presence validation passes, I want to run an inclusion validation.

Right now I have :

validates :segment_type, presence: true, inclusion: { in: SEGMENT_TYPES }

I have tried splitting this up into two separate validations as follows:

validates :segment_type, presence: true
validates :segment_type, inclusion: { in: SEGMENT_TYPES }

But the problem is for both of the attempts above, when no value is included in the segment_type field, I get error messages for both responses:

Segment type can't be blank
Segment type is not included in the list

In this case, I would just want "Segment type can't be blank" and not the second message.

Is there any way that I can tell rails to do this conditional validation and give me the desired waterfall of error messages without me having to define a custom function, say segment_type_presence_and_inclusion_check that checks these conditions in sequence and calling it with validate :segment_type_presence_and_inclusion_check?

Upvotes: 14

Views: 8696

Answers (3)

Paul Alexander
Paul Alexander

Reputation: 32367

You should also be able to use allow_blank on the inclusion validation

validates :segment_type,
          presence: true,
          inclusion: { in: SEGMENT_TYPES, allow_blank: true }

Upvotes: 15

Michael Discenza
Michael Discenza

Reputation: 3330

I discovered that this works as well.

validates :segment_type, presence: true
validates :segment_type, inclusion: { in: SEGMENT_TYPES }, if: "segment_type.present?" 

Upvotes: 0

jvnill
jvnill

Reputation: 29599

pass in an if inside the inclusion option to check for the presence

validates :segment_type,
  presence: true,
  inclusion: { in: SEGMENT_TYPES, if: :segment_type_present? }

private

def segment_type_present?
  segment_type.present?
end

you can also use a proc

inclusion: { in: SEGMENT_TYPES, if: proc { |x| x.segment_type.present? } }

Upvotes: 12

Related Questions