ruby-on-rails 一个属性是否可以为所有查找器方法进行规范化?

olhwl3o2  于 2023-05-19  发布在  Ruby
关注(0)|答案(1)|浏览(129)

假设我有一个Rails5模型,其中有一个属性需要规范化,比如URL或电子邮件。

class Person < ApplicationRecord
  # Using the attribute_normalizer gem
  normalize_attributes :email, with :email

  ...
end

我希望当finder方法用于该模型时,搜索属性也被规范化。比如...

# This would match 'foo@example.com'
person = Person.find_by( email: 'FOO@EXAMPLE.COM' )

# This would also match 'foo@example.com'
person = Person.find_by( email: 'foo+extra@example.com' )

我尝试提供自己的Person.find_by,以为其他查找器方法最终会调用它。

def self.find_by(*args)
  attrs = args.first
  normalize_email_attribute(attrs) if attrs.kind_of?(Hash) 
  super
end

这适用于Person.find_by,但尽管Rails内部使用find_by作为其他finder方法(如find_or_create_by),但它们不调用Person.find_by。我必须覆盖单个查找器方法。

def self.find_or_create_by(attrs, &block)
  normalize_email_attribute(attrs)
  super
end

def self.find_or_create_by!(attrs, &block)
  normalize_email_attribute(attrs)
  super
end

有没有一种方法可以在一个特定的模型上为所有的查找器方法规范化搜索属性?或者更好地完成同样的事情?

mv1qrgav

mv1qrgav1#

Rails 7.1添加了ActiveRecord::Base::normalizes

class User < ApplicationRecord
  normalizes :email, with: ->(email) { email.strip.downcase }
end

它同时适用于持久性和查找器方法

User.create(email: " ASDF@ExAmPLE.com \n")
# => #<User email: "asdf@example.com">

User.find_by(email: "\nasdf@examplE.CoM \t")
# => #<User email: "asdf@example.com">

相关问题