Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validation just for new records

I have a model Order with the price attribute.

There are few Order records in the database without a price attribute(nil value) which was imported from the old database. There are less than 20 invalid records like this.

Now the price attribute is mandatory.

I need to add a presence validation of the price and preserve the old records. I can't set the nil values to zero or some random values.

I have some crazy ideas about the conditional validation on the basis of the timestamp or even a list of "permitted" ids.

Something like this:

PERMITTED_IDS = [4, 8, 15, 16, 23, 42]
validates :price, presence: true, if: -> { |order| PERMITTED_IDS.exclude?(order.id) } 

Is there any nice and convenient way for that?

like image 467
freemanoid Avatar asked Sep 04 '25 16:09

freemanoid


2 Answers

Use on: :create

The following will only validate when the model is created.

validates :price, presence: true, on: :create

However, can't you just use allow_nil: true:

validates :price, presence: true, allow_nil: true
like image 145
j-dexx Avatar answered Sep 07 '25 05:09

j-dexx


I would add a boolean imported attribute to the Order class, setting it to true for old records upon import. This allows you to skip validations for these records easily:

validates :price, presence: true, unless: :imported?

UPDATE

Stefan: Are old/imported records editable?

freemanoid: @Stefan yes, but I can't set the price to zero for them.

The above solution is not an option because it would allow a nil price for all old records.

You could use a custom validation that requires a price for new records, but allows nil when updating records if the price was already nil. Something like:

validates :price, presence: true,
                  on: :create

validates :price, presence: true,
                  on: :update,
                  unless: Proc.new { |o| p.price_was.nil? }
like image 27
Stefan Avatar answered Sep 07 '25 07:09

Stefan