Ruby on rails Rails在查找或创建之前进行规范化

Ruby on rails Rails在查找或创建之前进行规范化,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,我有一个需要唯一地址字段的模型: class AddressMeta < AR::Base def normalize # normalize and store full_address end validates_uniqueness_of :full_address after_validation :normalize end 这两个地址显然是相同的,但我无法在数据库中找到第二个地址,除非首先对其进行规范化以匹配第一个地址。因此,如果第一个存在,并且我

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

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

  validates_uniqueness_of :full_address

  after_validation :normalize
end
这两个地址显然是相同的,但我无法在数据库中找到第二个地址,除非首先对其进行规范化以匹配第一个地址。因此,如果第一个存在,并且我在第二个上运行
find\u或\u create\u by(full\u address:address)
调用,我将丢失搜索并创建一个新对象,这将导致冲突


所以-我的问题。在Rails/AR中,如何在执行搜索之前规范find\u或create\u by方法的输入?或者有没有更好的方法来处理在规范化字段后在唯一字段上发生冲突的情况?

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

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
类地址meta
这样唯一性验证器就可以工作了。另外,一个很好的重构是将地址规范化逻辑提取到它自己的类中:

# 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    
#lib/address_converter.rb
类地址转换器

全班同学都有很好的建议。我最终创建了一个新的静态方法
normalized\u find\u或\u create
,在搜索之前对其进行地理编码,如果找不到,则创建一个新对象+1将逻辑引入到它自己的类中——我也这么做了。
# 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