如何将对象转换为字符串以用于ActiveRecord查询? [英] How can I cast an object to string for use with ActiveRecord queries?
问题描述
我有一个用户
,其中有一个 String
电子邮件
属性。但是,当我在应用程序中处理电子邮件时,我发现最好先将其转换为(非持久性) Email
对象,如下所示:
I have a User
, which has a String
email
attribute. However, when I'm dealing with an email in my app, I find it desirable to first convert it to a (non-persisted) Email
object, like so:
class User < ActiveRecord::Base
def email
Email.new(self.read_attribute :email)
end
end
Email#to_s
和 Email#to_str
都被定义为只能是原始字符串(例如, foo@bar.com
),因此对于客户来说,无论他们是否处理电子邮件,它通常都是相当透明的
或 String
。
Email#to_s
and Email#to_str
are both defined to be simply the original string (e.g., foo@bar.com
), so it's usually pretty transparent to the client whether they're dealing with an Email
or a String
.
这在使用 ActiveRecord
分配属性时非常有效:
This works perfectly when assigning attributes with ActiveRecord
:
> email = Email.new('foo@bar.com')
> user.email = email
ActiveRecord知道电子邮件
属性是一个字符串,并相应地转换 Email
对象。令人费解的是,查询数据库时不会执行此操作:
ActiveRecord knows that the email
attribute is a string and converts the Email
object accordingly. Somewhat puzzlingly, it doesn't do this when querying the database:
> 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
但是有没有办法使这种转换自动发生? / p>
But is there a way to make this cast happen automatically?
推荐答案
这是负责任的对象,用于将对象强制转换为ActiveModel中的字符串。看看 serialize 方法:没有处理电子邮件
的情况。
This is the responsible object for casting an object to a string in ActiveModel. Take a look at the serialize method there: it doesn't have a case for handling Email
.
您可以添加一个通过扩展类:
You can add one by extending the class:
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')
这篇关于如何将对象转换为字符串以用于ActiveRecord查询?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!