2013-01-21 19 views
9

Pracuję nad małym projektem ODM podobnym do DataMapper i próbuję użyć komponentu ActiveModel::Validations. Jednak wpadłem na problem podczas pisania testów - Używam anonimowych klas skonstruować moje schematy testów, jednak jeśli chodzi o uruchamianie weryfikatorów, klasa ActiveModel::Name rzuca błąd: Class name cannot be blank. You need to supply a name argument when anonymous class givenActiveModel :: Validations na anonimowej klasie

Oto prosty kod przykładem odtworzyć:

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 

wyjątkiem jest wywoływane tylko wtedy, gdy istnieje udało walidator - Zgaduję problem dzieje się, gdy próbuje skonstruować komunikat o błędzie sprawdzania poprawności. Moje pytanie brzmi:

  • Zrobiłem wiele wyszukiwania, ale nie mogłem znaleźć nikogo, kto próbowałby zrobić coś podobnego. Czy to nie jest możliwe z ActiveModel, czy istnieje obejście, o którym nie wiem?

Odpowiedz

14

ActiveModel próbuje uzyskać nazwę modelu (jak widać tutaj) podczas konfigurowania komunikatów o błędach. Najszybszym sposobem obejścia tego problemu (poza nadaniem nazwy anonimowej klasie) jest nadanie klasie klasy klasy model_name, która zwraca instancję o numerze ActiveModel::Name.

np

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

Dzięki, dokładnie to, co chciałem! Zauważyłem, że 'ActiveModel :: Name' może przyjąć nazwę klasy jako argument, ale nie zauważyłem, że mogę zwrócić własną instancję za pomocą' self.model_name'. Kolejny powód, dla którego nie programować późno w nocy ...: P – motns

+0

Dlaczego zwracać instancję 'ActiveModel :: Name' zamiast zwykłego łańcucha z' .model_name'? –

+0

To było 2 lata temu, ale IIRC, proces sprawdzania poprawności oczekuje (oczekiwany?) Instancji ActiveModel :: Name z tej metody. –

6

Błąd jest wyrzucane w funkcji initialize z 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 

Więc zamiast definiowania metody klasy model_name która zwraca ActiveModel::Name można definiować metody klasy name która zwraca 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 
Powiązane problemy