2010-10-19 4 views
4

Mise à jour (4 décembre 2010):Rails: Conserver toutes les lignes ActiveRecord "validates" dans un fichier séparé?

Je réalise que chaque ligne validates est en fait un appel de méthode (évidemment) afin de les exiger comme celui-ci ne faisait pas exactement comme je m'y attendais.

Cela fonctionne, mais je ne suis pas sûr qu'il est correct (saisir le nom complet de la classe Auction):

class Auction::Validations 
    Auction.validates :status, :presence => true, 
        :inclusion => { :in => [ 
         Auction::CREATING, 
         Auction::OPEN, 
         Auction::PENDING, 
         Auction::CANCELLED, 
         Auction::SUSPENDED, 
         Auction::EXPIRED, 
         Auction::CLOSING_COMPLETED, 
         Auction::CLOSING_WON, 
         Auction::COMPLETED, 
         Auction::WON, 
         Auction::NEGOTIATING, 
         Auction::IN_ESCROW 
        ] } 
    Auction.validates :user, :presence => true 
    Auction.validates :url, :presence => true, 
        # FIXME: Move this to a URLValidator and do :url => true 
        :format => /^https?:\/\/[a-z0-9-]+(\.[a-z0-9-])*\.[a-z0-9]+\/.*/i 
    Auction.validates :title, :presence => true, 
        :length => { :maximum => 255 } 
    Auction.validates :description, :presence => true 
    Auction.validates :reserve, :numericality => { :greater_than_or_equal_to => :minimum_bid } 
end 

Lorsque cela est nécessaire (require 'auction/validations) dans la classe Auction, il fait la bonne chose.

Question originale suit:

Un couple de mes classes de modèle sont un peu encombré avec tous ces « valide » les appels, donc je pensais que je serais capable de les déplacer dans une catégorie distincte et « exigent » ça, mais ça ne semble pas marcher.

class Auction < ActiveRecord::Base 
    require 'auction/validations' 
    ... 

class Auction::Validations 
    include ActiveModel::Validations 

    validates :status, :presence => true, 
        :inclusion => { :in => [ 
         ... snip ... 
        ] } 
    validates :user, :presence => true 
    validates :url, :presence => true, 
        # FIXME: Move this to a URLValidator 
        :format => /^https?:\/\/[a-z0-9-]+(\.[a-z0-9-])*\.[a-z0-9]+\/.*/i 
    validates :title, :presence => true, 
        :length => { :maximum => 255 } 
    validates :description, :presence => true 
    validates :reserve, :numericality => { :greater_than_or_equal_to => :minimum_bid } 

    validates_each :status, :on => :update do |auction, status_attr, value| 
    if auction.state_machine.current_state != value 
     # FIXME: Raise an Exception instead; this is a developer error, not a user error 
     auction.errors.add status_attr, "Status cannot be changed directly" 
    end 
    end 
end 

Il ne l'erreur pas, mais le validates_each n'exécute pas le bloc du tout (testé en ajoutant un puts "here"), et le contrôle de numéricité ne fonctionne plus.

Avec le corps de cette classe copié aveuglément dans la classe de vente aux enchères à nouveau tout fonctionne. Est-ce que je ne comprends pas ce que le «besoin» va faire avec ces validations?

EDIT:

En fait, aucun des validations travaillent. Pas seulement ces deux-là. Hmmm.

+0

Comme ceci: http://stackoverflow.com/a/27460841/115363 –

Répondre

0

Pourquoi ne pas inclure votre module?

module Auction::Validations 
    extend ActiveSupport::Concern 
    def included(base) 
    validates :status, :presence => true, 
        :inclusion => { :in => [ 
         ... snip ... 
        ] } 
    validates :user, :presence => true 
    validates :url, :presence => true, 
        # FIXME: Move this to a URLValidator 
        :format => /^https?:\/\/[a-z0-9-]+(\.[a-z0-9-])*\.[a-z0-9]+\/.*/i 
    validates :title, :presence => true, 
        :length => { :maximum => 255 } 
    validates :description, :presence => true 
    validates :reserve, :numericality => { :greater_than_or_equal_to => :minimum_bid } 

    validates_each :status, :on => :update do |auction, status_attr, value| 
    if auction.state_machine.current_state != value 
     # FIXME: Raise an Exception instead; this is a developer error, not a user error 
     auction.errors.add status_attr, "Status cannot be changed directly" 
    end 
    end 
    end 
end 
+0

Hmmm, je ne avais jamais vu auparavant. Très nouveau à la fois rubis et Rails, merci. – d11wtq

+0

Cependant, cela ne semble pas fonctionner. J'ai les mêmes résultats. Après d'autres tests, j'ai constaté que, en fait, aucun code dans cette classe requise ne fonctionne comme prévu. Comment puis-je l'apporter dans mon cours de vente aux enchères? – d11wtq

1

Put à la fin de l'enchère :: Validations:

Auction.send :extend, Auction::Validations 

et à la fin de vente aux enchères qui exigent la ligne.

+0

Merci. Malheureusement, cela ne semble pas avoir fonctionné non plus. Je dois faire quelque chose de mal.Si quelqu'un pouvait poster un exemple de code vraiment court d'un modèle (un seul champ suffira) et une classe séparée contenant toutes les validations, ce serait génial. J'ai juste abandonné à la fin et concédé que mes classes de modèle devront contenir ce fouillis. – d11wtq

+0

Je pense que le problème est qu'ils ne sont pas de nouvelles méthodes ajoutées, ce sont des appels de méthode réels qui sont faits. – d11wtq

+0

Ok, eh bien, j'ai trouvé un moyen après que quelque chose m'est apparu en faisant ce dernier commentaire. Question mise à jour ... – d11wtq

2

Je ne sais pas si cela est juste, mais il fonctionne en quelque sorte pour moi:

module MyValidations 
    module User 
    def self.included(base) 
     base.validates_presence_of :firstname 
    end 
    end end 

Alors u peut appeler

User.class_eval do 
    include MyValidations::User 
end 

espoir qui aide.

0

Dans Rails 4, c'est facile. Utilisez les préoccupations du modèle.

# put this into: app/models/concerns/auction/validations.rb 
class Auction 
    module Validations 
    extend ActiveSupport::Concern 

    included do 
     validates :status, presence: true 
    end 
    end 
end 

class Auction 
    include Validations 

    # other model code... 
end 
Questions connexes