2015-07-19 2 views
1

J'ai fait un petit plugin DRY que je veux utiliser dans certaines de mes classes (comme le théâtre, coffeeshop, restaurant, etc) plus tard. Toutes ces classes se composent d'une adresse et par conséquent, j'ai fait un plugin de modèle d'adresse avec une méthode act_as_address qui doivent être appelés par ces classes pour éviter d'écrire du code en double.Ruby on Rails plugin - Ajout de la validation en classe ne fonctionne pas correctement

Les classes se composent de quelques validations sur les champs d'adresse (comme la présence et de la longueur) et moi class_eval à l'intérieur du act_as_address dans le modèle d'adresses pour écrire ces validations aux classes. Cependant, cela ne semble pas fonctionner.

Voici mon code et les tests:

# structure.sql 
create table addresses (
    some_info varchar(25) 
    # other attrs 
); 

create table theatres (
    id integer, 
    primary key (id) 
) inherits (addresses); 


# act_as_address.rb 
module Address 
    module ActsAsAddress 
    extend ActiveSupport::Concern 

    include do 
    end 

    module ClassMethods 
     def acts_as_address 
     class_eval do <<-EVAL 
     validates :some_info, presence: true 
     # some other validations, methods etc. 
     EVAL 
     end 
     end 
    end 
    end 
end 

ActiveRecord::Base.send :include, Address::ActsAsAddress 

# theatre.rb 
class Theatre < ActiveRecord::Base 
    acts_as_address 
end 

# address.rb 
require 'address/acts_as_address' 

module Address 
end 

# acts_as_address_test.rb 
require File.expand_path('../test_helper', __FILE__) 

class ActsAsAddressTest < ActiveSupport::TestCase 
    test "should not be valid" do 
    assert_not Theatre.create(:some_info => nil).valid?, 
     "some_info was valid with nil value" 
    end 
end 

Et le résultat du test est la suivante:

1) Failure: 
ActsAsAddressTest#test_should_not_be_valid [acts_as_address_test.rb:16]: 
some_info was valid with nil value 

Quelqu'un pourrait-il me aider? Est-ce que class_eval le problème ici? J'utilise Ruby on Rails 4.

+0

Pourquoi avez-vous besoin class_eval du tout? Serez-vous dynamiquement générer du code? –

+0

Comme je l'ai dit dans mon post, car j'aurai plus de cours comme le Théâtre: comme Coffeeshop, Restaurant etc. Mon idée est d'écrire act_as_addresses dans ces classes pour ne pas avoir à y mettre les validations d'adresses (rester DRY). – maikovich

+0

OK mais je ne pense toujours pas que cela nécessite class_eval. validates est juste une méthode de classe qui a déjà été définie. Vous avez juste besoin de transmettre les bons arguments (c'est-à-dire les noms de colonnes et les validations spécifiques). Class_eval ne serait nécessaire que si vous vouliez définir une toute nouvelle méthode (et même alors, il existe de meilleures façons de le faire). –

Répondre

2

Vous pouvez être en mesure de le faire:

module Address 
    module ActsAsAddress 
    extend ActiveSupport::Concern 

    module ClassMethods 
     def acts_as_address 
     validates :some_info, presence: true 
     end 
    end 
    end 
end