You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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+\z ensures 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 produce nil or non-integer values.
  • Custom error messages are tailored to each failure scenario, making it easier for users to correct their input.

内容的提问来源于stack exchange,提问作者majk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 13:14:09