Ich habe eine User
, die ein String
email
Attribut hat. Allerdings, wenn ich mit einer E-Mail in meiner app zu tun habe, finde ich es wünschenswert, zuerst konvertiert es zu einem (nicht bestanden) Email
Objekt, etwa so:Wie kann ich ein Objekt in eine Zeichenfolge für die Verwendung mit ActiveRecord-Abfragen umwandeln?
class User < ActiveRecord::Base
def email
Email.new(self.read_attribute :email)
end
end
Email#to_s
und Email#to_str
sind beide definiert werden einfach die ursprüngliche Zeichenkette (zB [email protected]
), so ist es für den Client normalerweise ziemlich transparent, ob es sich um eine Email
oder eine String
handelt.
Dies funktioniert perfekt, wenn Attribute mit ActiveRecord
zuweisen:
> email = Email.new('[email protected]')
> user.email = email
Active weiß, dass das email
Attribut ist ein String und wandelt das Email
Objekt entsprechend. Etwas rätselhaft, ist es dies nicht tun, wenn die Datenbank abfragt: Offensichtlich
> email = Email.new('[email protected]')
> User.find_by email: email
ActiveRecord::StatementInvalid: can't cast Email to string
, kann ich
> User.find_by email: email.to_s
rufen Sie einfach aber ist es eine Möglichkeit, diese Besetzung automatisch geschieht?
Welche Version von Rails verwenden Sie? Für Rails 4.2 und höher können Sie ['attribute'] (http://apidock.com/rails/v4.2.7/ActiveRecord/Attributes/ClassMethods/attribute) verwenden, um das Typcasting-Verhalten zu steuern. – Max
@Max Er müsste ein benutzerdefiniertes 'Type' für' attribute' definieren, um zu funktionieren, da das AR den gewünschten Typ bereits korrekt aus der Datenbank ableitet, aber der Standard 'Type' nicht weiß, wie er mit' Email' umgehen soll. Eine andere Option wäre, dass "Email" von "String" erbt (oder die Case-Gleichheitsoperatormethode auf "String" patchen). – coreyward
@coreyward Ja, ich dachte an einen benutzerdefinierten Typ, der 'to_s' aufrufen würde. Ich dachte, es wäre sauberer als das Überschreiben von Dingen in 'ActiveModel', aber das Definieren eines benutzerdefinierten Typs könnte übertrieben sein, nur um' to_s' zu erhalten. Wahrscheinlich hängt es davon ab, ob dies ein allgemeines Muster für das OP ist und es für zusätzliche Klassen arbeiten muss. – Max