如何将对象转换为字符串以用于ActiveRecord查询?

我有一个User ,它有一个String email属性。 但是,当我在我的应用程序中处理电子邮件时,我发现首先将其转换为(非持久的) Email对象是可取的,如下所示:

 class User < ActiveRecord::Base def email Email.new(self.read_attribute :email) end end 

Email#to_s Email#to_strEmail#to_str都被定义为原始字符串(例如, Email#to_str ),因此无论客户是处理Email还是String ,它通常都非常透明。

使用ActiveRecord分配属性时,这非常有效:

 > email = Email.new('foo@bar.com') > user.email = email 

ActiveRecord知道email属性是一个字符串并相应地转换Email对象。 有点令人费解的是,在查询数据库时它不会这样做:

 > email = Email.new('foo@bar.com') > User.find_by email: email ActiveRecord::StatementInvalid: can't cast Email to string 

显然,我可以打电话

 > User.find_by email: email.to_s 

但有没有办法让这个演员自动发生?

这是将对象强制转换为ActiveModel中的字符串的负责对象 。 看看那里的序列化方法:它没有处理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('foo@example.org') 

您可以覆盖模型中的getter方法来强制转换并返回字符串。