以下代码适用于创建具有电子邮件或电话等地址的“频道”。
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时,如何测试我正在以某种方式传递给类的新值?鉴于上面的代码,我唯一可以看到的是删除频道并创建一个具有不同格式的新频道。
答案 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?