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.
Pourquoi avez-vous besoin class_eval du tout? Serez-vous dynamiquement générer du code? –
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
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). –