开发者

How to validate against the object "in memory" versus the stored object in the database

The following code works just fine on creating "channels" that have an address like emails or phones.

class Channel < ActiveRecord::Base
  belongs_to :contact
  belongs_to :mechanism

  validates_uniqueness_of :address
  validates_format_of :address, :with => /@/i,
    :if => :address_is_email?
  validates_format_of :address, :with => /\d\d\d\d\d\d\d\d\d\d/,
    :if => :address_is_phone?

  def before_validation
    self.address = address.gsub(/[^0-9]/, "") if mechanism.designation == "sms"
  end

  def address_is_email?
    mechanism.designation == "smtp"
  end

  def address_is_phone?
    mechanism.designation == 开发者_StackOverflow社区"sms"
  end
end

Like so:

>> c = Channel.create(:mechanism_id => 1, :address => 'something@someplace.com')
=> #<Channel id: 17, created_at: "2010-12-02 15:00:59", updated_at: "2010-12-02 15:00:59", mechanism_id: 1, contact_id: nil, address: "something@someplace.com", enabled: nil, time_window_id: nil>
>> c.save
=> true

However, if I try to change the format from one to the other after the fact, it will fail.

>> c.update_attributes(:address => '888.555.1212', :mechanism_id => 2)
=> false
>> c.save
=> false

I'm guessing that this is because the validates_format_of is going through the address_is_*? function, and reading against the format that's stored in the database (or in memory already), and NOT against the value I'm feeding it. How would I test against the new value that I'm passing (somehow) to the class when I try to do the update_attributes? The only thing I can see to do, given the code above, is delete the channel and create a new one with the different format.


Your problem is with this line:

validates_format_of :address, :with => /\d\d\d\d\d\d\d\d\d\d/,
    :if => :address_is_phone?

The regular expression is expecting 10 digits, with nothing in between! If you want dots, like your example above, do it like this:

validates_format_of :address, :with => /\d\d\d\.\d\d\d\.\d\d\d\d/,
    :if => :address_is_phone?

And of course, you can get as complex as you want from there. I hope this helps!

PS: This is a shorter, easier to read version:

validates_format_of :address, :with => /\d{3}\.\d{3}\.\d{4}/,
    :if => :address_is_phone?
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜