Rails在find_or_create之前归一化 [英] Rails normalize before find_or_create

查看:65
本文介绍了Rails在find_or_create之前归一化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个模型,其中的地址字段需要唯一:

I have a model with an address field that needs to be unique:

class AddressMeta < AR::Base
  def normalize
    # normalize and store full_address
  end

  validates_uniqueness_of :full_address

  after_validation :normalize
end

我正在通过地址解析API传递地址,以确保地址在存储之前是有效的和规范化的。我遇到的麻烦是我也希望地址唯一,因此每个唯一的地址字符串只有一条记录。采取以下地址:

I am passing addresses through a geocoding API to ensure that they are valid and normalized before storing. The trouble I'm running into is that I also want addresses to be unique, so there's only a single record per unique address string. Take the following addresses:

101 E 1st St #101, Austin, TX
101 E 1st Street Suite 101, Austin, TX

这两个地址显然是同一地址,但我在地址中找不到第二个地址除非首先对其进行标准化以使其与第一个数据库匹配。因此,如果第一个存在并且在第二个上运行 find_or_create_by(full_address:address)调用,我最终会丢失搜索并创建一个新对象,结果

These two are obviously the same address, but I can't find the second in the database unless it is first normalized to match the first. So if the first one exists and I run a find_or_create_by(full_address: address) call on the second, I end up missing with the search and creating a new object, and this results in a collision.

所以-我的问题。在Rails / AR中,如何在执行搜索之前将输入标准化为find_or_create_by方法?还是有更好的方法来处理规范化字段后在唯一字段上发生冲突的情况?

So - my question. In Rails/AR, how can I normalize the input to the find_or_create_by method prior to performing the search? Or is there a better way to handle the case that I have a collision on a unique field after normalizing a field?

推荐答案

没有代码的完整上下文很难确定,但是一种解决方案是在 验证之前而不是之后进行更改标准化执行:

It's difficult to determine without the full context of the code, however one solution is to change the normalize execution to occur before validation and not after:

class AddressMeta < AR::Base
  validates_uniqueness_of :full_address

  before_validation do
    full_address = normalize_address(full_address)
  end

  private
  def normalize_address(address_string)
    # Code to convert address with API
    # Returns normalized address string
  end
end

这样,唯一性验证器应该起作用。另外,一个很好的重构方法是将地址规范化逻辑提取到其自己的类中:

That way the uniqueness validator should work. Also, a nice little refactor would be to extract the address normalization logic out into its own class:

# lib/address_converter.rb
class AddressConverter
  class << self
    def normalize(raw_address)
      # Logic and API Code
      # Returns normalized string
    end
  end
end

# app/models/address_meta.rb
require 'address_converter'

class AddressMeta < AR::Base
  validates_uniqueness_of :full_address

  before_validation do
    full_address = AddressConverter::normalize(full_address)
  end
end    

这篇关于Rails在find_or_create之前归一化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆