Tintin81
Tintin81

Reputation: 10207

How to validate virtual attribute in Rails?

I have this class:

class Project < ActiveRecord::Base

  validates :hourly_rate, :numericality => { :greater_than_or_equal_to => 0 },
                          :allow_blank  => true

  def hourly_rate=(number)
    self.hourly_rate_in_cents = number.present? ? number.to_d * 100 : nil
  end

end

Essentially, any new hourly_rate that gets entered by the user will get saved to the database as an integer.

This works quite well for numbers.

But any string that is being entered, is automatically converted into 0.0 and gets saved without any validation message!

Isn't there a way to validate this using any of Rails' validation methods?

Thanks for any help.

Upvotes: 4

Views: 5463

Answers (2)

Bryce
Bryce

Reputation: 2872

You can create your own validate method and use that to check for the type of object.

For example (and forgive me if there's an error in this code, since it's just off the top of my head):

validate :hourly_rate_is_integer

def hourly_rate_is_integer
  errors.add(:hourly_rate, "must be Integer") unless self.hourly_rate.is_a?(Integer)
end

Upvotes: 4

tadman
tadman

Reputation: 211560

If you have a reader method for this that converts the other way, it will work as you expect. You've only shown the assignment method here.

def hourly_rate
  self.hourly_rate_in_cents and self.hourly_rate_in_cents.to_f / 100
end

All the validation routines do is call the given method and apply tests to the result.

You might want to ensure that presence is specifically tested:

validates :hourly_rate, :presence => true, ...

Upvotes: 3

Related Questions