基于ActiveRecord的字符串校验:将字符串部分内容视为整数处理
Solution for ActiveRecord Validation with String-to-Integer Conversion
Hey there! Let's break down how to implement your validation rules in Ruby 3.0.2 with ActiveRecord. The key here is safely splitting the input string, converting parts to integers, then applying your specific logic step by step.
Step 1: Add Basic Format Validation
First, ensure the input matches the "XX-XX" string format using a regex. This prevents invalid inputs before we even get to the number checks:
class YourModel < ApplicationRecord # Replace :input_field with your actual column name validates :input_field, format: { with: /\A\d+-\d+\z/, message: "must be in the format 'XX-XX' (e.g., '21-10')" }
Step 2: Implement Custom Number Validation Rules
Next, add a custom validation method to handle the integer conversion and your business rules. Here's how to translate your requirements into code:
validate :validate_number_rules private def validate_number_rules # Split the string and convert both parts to integers num1, num2 = input_field.split('-').map(&:to_i) # Define the two valid cases based on your rules valid_case_1 = (num1 == 21 || num2 == 21) && num1 <= 21 && num2 <= 21 valid_case_2 = (num1 > 21 && num2 > 21) && (num1 - num2).abs == 2 # Check if either case is satisfied unless valid_case_1 || valid_case_2 # Add specific error messages based on what went wrong if (num1 > 21 || num2 > 21) && !(num1 > 21 && num2 > 21) errors.add(:input_field, "can't have a single number greater than 21. Either include 21 (with both numbers ≤21) or use two numbers >21 with a difference of 2") elsif num1 <= 21 && num2 <= 21 && num1 != 21 && num2 != 21 errors.add(:input_field, "must include 21 (when numbers are ≤21) or use two numbers >21 with a difference of 2") elsif (num1 > 21 && num2 > 21) errors.add(:input_field, "both numbers greater than 21 must have an absolute difference of exactly 2") end end end end
How This Works with Your Examples
Let’s verify against your test cases:
- Valid: "11-21": Matches
valid_case_1(includes 21, both numbers are ≤21) - Valid: "22-24": Matches
valid_case_2(both numbers >21, absolute difference is 2) - Invalid: "10-23": Triggers the first error (single number >21, no 21 present)
- Invalid: "11-11": Triggers the second error (no 21, both numbers ≤21)
Quick Notes
- The regex
\A\d+-\d+\zensures the input starts and ends with numbers separated by exactly one hyphen—no extra characters allowed. - Using
map(&:to_i)safely converts each split part to an integer; since we already validated the format, this won’t producenilor non-integer values. - Custom error messages are tailored to each failure scenario, making it easier for users to correct their input.
内容的提问来源于stack exchange,提问作者majk
相关产品推荐
相关产品推荐

