【问题标题】:rails 3: on create, how do I validate a 'referral code' form field with a custom method that verifies the referral code exists in another table?rails 3:在创建时,如何使用自定义方法验证“推荐代码”表单字段,该方法验证推荐代码是否存在于另一个表中?
【发布时间】:2025-12-07 12:00:01
【问题描述】:

这可能是一个简单的验证问题,但我只有使用内置 rails 验证助手的经验,例如允许字段为空白和/或强制执行特定长度或匹配正则表达式。

当用户注册(使用 Devise)时,我的注册表单(和用户架构)还有一个“referred_by”字段,他们可以在其中输入推荐代码(例如销售代表 ID)。

“referred_by”字段在保存之前需要进行一些特殊验证: * 删除所有空格 * 强制小写 * 验证它是一个允许的“推荐代码”值(存在于 ReferralCodes 表的“代码”字段中)

如果它不是一个允许的值(例如,在 ReferralCode 表中不存在),我需要在表单上标记一个验证错误,例如“这不是一个有效的推荐代码”

我不知道将方法放在哪里,所以在尝试保存数据时它会作为 Rails 验证的一部分自动触发...

任何帮助将不胜感激!

【问题讨论】:

    标签: ruby-on-rails validation


    【解决方案1】:

    您需要一个自定义验证器,并对模型中的数据进行一些清理。

    app/models/user.rb:

    class User < ActiveRecord::Base
      validates_with ReferralValidator
    
      before_save :clean_referral
    
      def clean_referral
        self.referred_by = self.referred_by.strip.lowercase
      end
    
    end
    

    app/lib/validators/referral_validator.rb:

    class ReferralValidator < ActiveModel::Validator
      def validate(record)
        record.errors[:base] << "#{record.referred_by} is not a valid referral code" unless referral_code_valid?
      end
    end
    

    您必须定义referral_code_valid?使用您希望将引用代码分类为有效的任何逻辑,并确保将 lib 目录的自动加载添加到您的配置中。您可以在 config/application.rb 中使用以下内容:

    config.autoload_path += %W({config.root}/lib)
    

    【讨论】:

    • 有没有办法让验证器也突出显示验证失败的字段?
    • 想通了。将 [:base] 更改为 [:FIELDNAME]。不过,我没有使用单独的 lib 文件等或 validates_with,只是将验证方法放在 User 类中并使用 validate :valid_referral, :on => :create
    最近更新 更多