如何验证“在内存中”对象与数据库中的存储对象

时间:2010-12-02 15:25:36

标签: ruby-on-rails

以下代码适用于创建具有电子邮件或电话等地址的“频道”。

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 == "sms"
  end
end

像这样:

>> 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

但是,如果我尝试在事后将格式从一个更改为另一个,则会失败。

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

我猜这是因为validates_format_of正在通过address_is_ *?函数,并根据存储在数据库中(或已经在内存中)的格式进行读取,而不是反对我正在提供它的值。当我尝试执行update_attributes时,如何测试我正在以某种方式传递给类的新值?鉴于上面的代码,我唯一可以看到的是删除频道并创建一个具有不同格式的新频道。

1 个答案:

答案 0 :(得分:1)

你的问题在于这一行:

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

正则表达式期待10位数,中间没有任何内容!如果您想要点,就像上面的示例一样,请执行以下操作:

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

当然,你可以从那里得到你想要的复杂。我希望这有帮助!

PS:这是一个更简单,更易读的版本:

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