在我为Rails 2.3.5的lib /目录放入的代码中找到合适的混合方法时遇到了一些困难。
我有几种需要手机验证的型号。我至少有三个使用相同代码的模型,所以我想保持DRY并将其移到lib /目录中。我曾经在每个模型中都有这样的代码:
validate :phone_is_valid
然后我在模型中有一个phone_is_valid方法:
protected
def phone_is_valid
# process a bunch of logic
errors.add_to_base("invalid phone") if validation failed
end
我将这段代码移到lib / phones /中,在lib / phones中我有lib / phones / phone_validation.rb,在那里我复制粘贴了phone_is_valid方法。
我的问题是,我现在如何将它混合到我的所有模型中?我的验证:phone_is_valid方法是保持不变还是更改?我想确保errors.add_to_base方法继续像以前一样运行,同时保持一切干燥。显然以下内容不起作用:
validate :Phones::PhoneValidation::phone_is_valid(number)
我还在lib / phones /中创建了另一个名为lib / phones / phone_normalize.rb的文件。同样,许多模型需要用户输入的值进行标准化。含义转(555)222-1212至5552221212或类似的东西。我可以通过调用Phones :: Phone_Normalize :: normalize_method(number)来调用它吗?
我想我对以下内容感到困惑:
答案 0 :(得分:2)
class Profile < ActiveRecord::Base
include Phones::PhoneValidation
validate_phone_is_valid
end
如果您想将它用于许多模型,那么您可能会将验证直接修补到ActiveRecord中:
module ActiveRecord
module Validations
module ClassMethods
def validates_photo(*attr_names)
# ....
end
end
end
end
答案 1 :(得分:1)
一点元编程魔法?
module Phones
def self.included(base)
base.send :extend, ClassMethods
end
module ClassMethods
def validate_phone(*attr_names)
#setup the config array eg. configuration = atrr.extract_options!
validates_each(attr_names, configuration) do |record, attr_name, value|
record.errors.add(attr_name, configuration[:message]) unless #validation
end
#setup the phone normalization
unless configuration[:normalize]
before_save do
# normalization code here
end
end
end
end
end
ActiveRecord::Base.send :include, Phones
然后在你的模型中:
validate_phone :main_phone, :cellphone, :message => "not a valid telephone number"