2013-01-21 36 views
9

Sto lavorando a un piccolo progetto ODM simile a DataMapper e sto cercando di utilizzare il componente ActiveModel::Validations. Tuttavia, mi sono imbattuto in un problema durante la scrittura test - Io sto usando classi anonime per costruire i miei schemi di test, tuttavia quando si tratta di esecuzione i validatori, la classe ActiveModel::Name sta gettando un errore: Class name cannot be blank. You need to supply a name argument when anonymous class givenActiveModel :: Validazioni sulla classe anonima

Ecco un semplice codice esempio per riprodurre:

require 'active_model' 

book_class = Class.new do 
    include ActiveModel::Validations 

    validates_presence_of :title 

    def title; ""; end # This will fail validation 
end 

book_class.new.valid? # => throws error 

l'eccezione viene generato solo quando c'è un validatore fallito - sto cercando di indovinare il problema si verifica quando si cerca di costruire il messaggio di errore di convalida. Quindi la mia domanda è:

  • Ho fatto un sacco di ricerche, ma non ho trovato nessuno che cercasse di fare qualcosa di simile. Questo semplicemente non è possibile con ActiveModel, o c'è una soluzione di cui non sono a conoscenza?

risposta

14

ActiveModel tenta di ottenere il nome del modello (come si vede qui) quando si impostano i messaggi di errore. Il modo più rapido per aggirare il problema (non dare un nome alla classe anonima) è quello di fornire alla classe un metodo di classe model_name che restituisce un'istanza di ActiveModel::Name.

per esempio

require 'active_model' 

book_class = Class.new do 
    include ActiveModel::Validations 
    def self.model_name 
    ActiveModel::Name.new(self, nil, "temp") 
    end 
    validates_presence_of :title 

    def title; ""; end # This will fail validation 
end 

book_class.new.valid? # => no error 
+0

Grazie, esattamente quello che volevo! Ho notato che 'ActiveModel :: Name' può assumere un nome di classe come argomento, ma non ha notato che posso restituire la mia istanza tramite' self.model_name'. Un altro motivo per non programmare a tarda notte ...: P – motns

+0

Perché restituire un'istanza di 'ActiveModel :: Name' anziché una stringa semplice da' .model_name'? –

+0

Questo era 2 anni fa, ma IIRC, il processo di validazione si aspetta (previsto?) Un'istanza di ActiveModel :: Name da quel metodo. –

6

L'errore viene gettata nella funzione di inizializzazione di ActiveModel::Namehere.

module ActiveModel 
    class Name 
    def initialize(klass, namespace = nil, name = nil) 
     @name = name || klass.name 

     raise ArgumentError, "Class name cannot be blank. You need to supply a name argument 
     # ... 
    end 
    end 
end 

Quindi, piuttosto che la definizione di un metodo di classe model_name che restituisce un ActiveModel::Name, è possibile definire un metodo di classe name che restituisce un String.

require 'active_model' 

book_class = Class.new do 
    include ActiveModel::Validations 
    validates_presence_of :title 

    def self.name 
    "Book" 
    end 

    def title; ""; end # This will fail validation 
end 

book_class.new.valid? # => false 
Problemi correlati