我有一个User
,其中有一个String
email
属性。但是,当我在应用程序中处理电子邮件时,我发现最好先将其转换为(非持久)Email
对象,就像这样:
class User < ActiveRecord::Base
def email
Email.new(self.read_attribute :email)
end
end
Email#to_s
and Email#to_str
都被定义为简单的原始字符串(例如,[email protected] /cdn-cgi/l/email-protection
),所以对于客户来说,他们是否正在处理一个通常是相当透明的Email
or a String
.
当分配属性时,这非常有效ActiveRecord
:
> email = Email.new('[email protected] /cdn-cgi/l/email-protection')
> user.email = email
ActiveRecord 知道email
属性是一个字符串并转换Email
相应地反对。有点令人费解的是,它在查询数据库时并没有这样做:
> email = Email.new('[email protected] /cdn-cgi/l/email-protection')
> User.find_by email: email
ActiveRecord::StatementInvalid: can't cast Email to string
显然,我可以打电话
> User.find_by email: email.to_s
但是有没有办法让这个转换自动发生呢?
这是负责的对象 https://github.com/rails/rails/blob/92703a9ea5d8b96f30e0b706b801c9185ef14f0e/activemodel/lib/active_model/type/immutable_string.rb用于将对象转换为 ActiveModel 中的字符串。看看连载 https://github.com/rails/rails/blob/92703a9ea5d8b96f30e0b706b801c9185ef14f0e/activemodel/lib/active_model/type/immutable_string.rb#L8-L15那里的方法:它没有处理的情况Email
.
您可以通过扩展类来添加一个:
module EmailSupport
def serialize(value)
case value
when Email then value.to_s
else super
end
end
end
ActiveModel::Type::ImmutableString.include(EmailSupport)
User.find_by email: Email.new('[email protected] /cdn-cgi/l/email-protection')
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)