How can I cast an object to string for use with ActiveRecord queries?

二次信任 提交于 2019-12-10 16:48:42

问题


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 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.

This works perfectly when assigning attributes with ActiveRecord:

> email = Email.new('foo@bar.com')
> user.email = 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

Obviously, I can just call

> User.find_by email: email.to_s

But is there a way to make this cast happen automatically?


回答1:


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')



回答2:


You can override the getter method in your model to cast it and return the string.



来源:https://stackoverflow.com/questions/42182553/how-can-i-cast-an-object-to-string-for-use-with-activerecord-queries

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!