ActiveRecord验证失效求助:如何强制验证模型额外字段?
Hmm, that's a weird one—you've got presence validations set up for pax and customer_email in your Referal model, but when those fields are nil, valid? is still returning true, and it only seems like the foreign key validations for business and referer are kicking in. Let's break this down and fix it.
First, Check the Exact Error Details
Don't just rely on the valid? boolean—let's see what the actual error messages (or lack thereof) tell us. Run this in your Rails console:
x = Referal.new(business_id: "224cd62b-3d29-41ca-a1be-f308815514b2", referer_id: "cdfb1861-d5e4-4650-9783-4189cffde6bd") x.valid? puts x.errors.full_messages
If the output is empty, your validations truly aren't firing. If there are errors, you might have misjudged what's happening earlier.
Verify Your Validation Syntax
Your current validation code is technically correct, but let's simplify and standardize it to rule out any subtle syntax quirks:
# Replace your two separate validates lines with this single line validates :pax, :customer_email, presence: true
This consolidated syntax is cleaner and eliminates any chance that the older hash rocket syntax (:presence => true) is causing issues.
Rule Out Code That's Interfering With Validations
Check for Callback Methods
Take a look at your model (or any concerns included in it) for before_validation or around_validation callbacks that might be modifying the pax or customer_email values before validation runs. For example:
# This would mess with your presence validation by setting an empty string before_validation :set_defaults def set_defaults self.pax ||= "" end
If you find any callbacks like this, comment them out temporarily and test the validation again.
Check for Accidental Attribute Overrides
Double-check if you've added attr_accessor :pax or attr_accessor :customer_email anywhere in the model. If these fields are actual database columns, adding attr_accessor would override the Active Record getter/setter, which could interfere with how validations read the values.
Disable Third-Party Gems Temporarily
If you're using gems that modify Active Record validation behavior (like validates_timeliness or custom validation gems), try disabling them temporarily. Sometimes these gems can override or interfere with default Rails validation logic.
Simplify the Model to Isolate the Issue
Strip down your model to only the essential code and test if the validations start working:
class Referal < ApplicationRecord validates :pax, :customer_email, presence: true belongs_to :referer, class_name: "User" belongs_to :customer, class_name: "User" belongs_to :business end
If the validations work now, gradually add back the default_scope, implicit_order_column, and any other code to figure out which part was causing the problem.
A Last-Ditch Trick to Force Validations
If all else fails, you can add a trivial condition to the validations to ensure they always run:
validates :pax, presence: true, if: -> { true } validates :customer_email, presence: true, if: -> { true }
This looks redundant, but it can rule out any hidden conditional logic that's accidentally skipping your validations.
内容的提问来源于stack exchange,提问作者Pierre

