【问题标题】:Rails: How do I validate against this code that I put into the lib/ directory?Rails:如何验证我放入 lib/ 目录的代码?
【发布时间】:2011-02-17 05:53:08
【问题描述】:

在找到正确的方法来混合我放入 Rails 2.3.5 的 lib/ 目录中的代码时有点困难。

我有几个需要电话验证的型号。我至少有三个使用相同代码的模型,所以我想保持干燥并将其移到 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 方法。

我的问题是,我现在如何将它混合到我的所有模型中?我的 validate :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) 来调用它吗?

我想我对以下内容感到困惑:

  • 如何使用 lib 目录来验证需要访问特定验证方法的多个模型
  • 如何将 lib 目录用于返回值的常用共享方法

【问题讨论】:

  • 我正在做一个需要验证电话号码的项目。我不知道您是否会觉得这很有用,但我将电话号码(及其可能的扩展名)放入了他们的 OWN 模型中。您可以使用此功能做的一件很酷的事情是,您可以搜索电话号码以查找与其相关联的 X、Y 或 Z 类型。我还有一个 before_save 方法,它在保存之前去掉所有的括号、连字符等,这样它们就可以很容易地搜索到,然后你可以很容易地在视图中格式化电话号码,使它们是统一的。希望这些想法有用。

标签: ruby-on-rails ruby activerecord


【解决方案1】:
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

【讨论】:

  • 不应该是 validate :phone_is_valid 吗?另外,如果我正在验证的列在不同的模型中有不同的名称怎么办。这意味着我需要能够将其作为参数传递给验证方法。我不喜欢直接将它烘焙到 ActiveRecord 中。
  • validate :phone_is_valid? 会在验证过程中调用 phone_is_valid? 方法,当然可以,但它超出了验证的命名约定。对于不同的属性名称,我已将 *attr_names 放入我的第二个代码示例中。
【解决方案2】:

有点元编程魔术?

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"

【讨论】:

    猜你喜欢
    • 2011-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-18
    相关资源
    最近更新 更多