如何创建Rails的Invoice模型Scope,匹配支付标签关联发票?
解决方案
核心思路是先从格式混乱的支付标签中提取出符合规则的参考号片段,再用该片段的两种形式(带连字符/不带连字符)去匹配发票的number和moneyin_key字段。
步骤说明
- 提取参考号片段:用正则从标签中匹配出符合参考号规则的子串(忽略大小写)
- 格式转换:将提取到的片段转换为两种格式:
- 原始格式(可能带连字符):匹配发票的
number字段 - 去掉所有连字符的格式:匹配发票的
moneyin_key字段,同时也可以匹配number字段去掉连字符后的内容
- 原始格式(可能带连字符):匹配发票的
- 构建查询条件:通过多条件匹配确保覆盖所有可能的情况
最终Scope代码
scope :related_to_payment_label, -> (label) { # 匹配标签中任意位置的参考号片段(忽略大小写) reference_regex = /[a-zA-Z]{2,5}-?\d{4}-?\d{2}-?\d{4}/i extracted_reference = label.match(reference_regex)&.to_s # 如果未提取到有效参考号,返回空集合 return none unless extracted_reference # 统一转为大写,匹配发票number的格式 normalized_reference = extracted_reference.upcase # 生成不带连字符的格式,匹配moneyin_key key_format = normalized_reference.gsub('-', '') # 多条件匹配:原始格式匹配number,无连字符格式匹配number(处理后)或moneyin_key where( "number ILIKE :reference_pattern OR REPLACE(number, '-', '') = :key_format OR moneyin_key = :key_format", reference_pattern: "%#{normalized_reference}%", key_format: key_format ) }
代码解释
- 正则提取:使用
/[a-zA-Z]{2,5}-?\d{4}-?\d{2}-?\d{4}/i匹配标签中嵌入的参考号,去掉了原正则的首尾锚点,允许参考号出现在标签的任意位置 - 大小写处理:将提取到的参考号转为大写,适配发票
number字段的大写格式 - 多条件匹配:
number ILIKE :reference_pattern:匹配带连字符的参考号(比如标签里是EDP-2023-10-0001,直接匹配发票的number)REPLACE(number, '-', '') = :key_format:处理标签里不带连字符的情况(比如EDP2023100001),将发票的number去掉连字符后匹配moneyin_key = :key_format:直接匹配发票的moneyin_key字段
内容的提问来源于stack exchange,提问作者raphael-allard
相关产品推荐
相关产品推荐

