Question

Say I have a custom setter on an activemodel model DateRange, to automatically set a DateTime attribute if a string is entered. It looks like this

  def from=(value)
    @from = value.to_date
  end

Now this does work if you enter a valid date string, but if you enter an invalid date, it stalls my application. How can I cancel assignment so that the application will move on and the DateRange fails validation later on in my controller?

Was it helpful?

Solution

def from=(value)
  begin
    @from = value.to_date
  rescue ArgumentError, NoMethodError
    errors.add(:from, "is not a valid date")
  end
end

Probably a better way to do it but that should work

OTHER TIPS

You would generally want to rescue/handle any problem in your setter.

def from=(value)
  @from = Date.parse(value)
rescue ArgumentError
  nil
end

Then let your normal date validations handle the nil value later.

I wouldn't add to your errors in the setter as it should not need to know about your validations and vice versa.

As @jordelver says, there is no point in adding validation errors except during validation. However, you can save the error in a virtual attribute and check for it during validation.

validate :no_bad_dates
attr_accessor :bad_date_error

def from=(value)
  @from = Date.parse(value)
rescue ArgumentError => ex
  self.bad_date_error = ex
end

def no_bad_dates()
  errors.add(:from, bad_date_error.message) if bad_date_error
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top