2010-11-20 15 views
0

J'ai deux modèles:Rails 3 - Validation avec 2 modèles et avertissements supplémentaires?

  • conférence
  • inscription

La conférence a une capacité et une liste d'attente. S'il y a une inscription pour une conférence, j'aimerais valider s'il y a des places libres disponibles.

a créé deux aides pour que:

def availableSeats 
    return self.capacity - self.enrollments.confirmedEnrollments.count 
end 

def waitListAvailable 
    return self.waitListCapacity - self.enrollments.waitList.count 
end 

Je pensais que d'avoir des contrôles dans le contrôleur d'inscription, mais il ne fonctionne pas.

if(@lecture.availableSeats <= 0) 
    if(@lecture.waitListAvailable <= 0) 
    flash[:error] = "Enrolment not possible as the waiting list is full." 
    # interrupt and don't save, but how? 
    else 
    flash[:warning] = "You are on the waiting list." 
    @enrollment.confirmed = nil 
    end 
else 
    @enrollment.confirmed = DateTime.now 
end 

Des idées comment cela fonctionnerait?

Répondre

1

Je suppose que votre modèle d'inscription définit à la fois les étudiants admis et ceux sur la liste d'attente. Je présume également que le modèle Lecture a deux attributs: available_seats et available_wait_space, et que la liste d'attente est remplie selon le principe du premier arrivé et que les étudiants sont refusés si la liste est complète, mais que les places réelles sont confirmées ou rejetées manuellement par le conférencier. .

Je déconseillerais certainement de faire quoi que ce soit au niveau du contrôleur. C'est un travail pour les modèles seulement.

class Enrollment < ActiveRecord::Base 
    belongs_to :student 
    belongs_to :lecture 

    validates_presence_of :student_id, :lecture_id, :status 
    validates_inclusion_of :status, :in => %w[waiting confirmed rejected] 
    validate :must_fit_in_wait_list, :on => :create 
    validate :must_fit_in_class,  :on => :update 

    scope :waiting, where(:status => 'waiting') 
    scope :confirmed, where(:status => 'confirmed') 
    scope :rejected, where(:status => 'rejected') 

    def must_fit_in_wait_list 
    unless waiting.count < lecture.available_wait_space 
     errors.add(:base, "The waiting list is full") 
    end 
    end 

    def must_fit_in_class 
    unless confirmed.count < lecture.available_seats 
     errors.add(:status, "The seats are full") 
    end 
    end 
end 

Par ailleurs, ne pas oublier de définir la valeur par défaut pour status à « en attente » dans vos migrations.

0

Merci Edgerunner pour la réponse! J'ai trouvé une autre solution facile:

validate do |enrollment| 
    if(enrollment.lecture.availableSeats <= 0) 
    enrollment.errors.add_to_base("This lecture is booked out.") if enrollment.lecture.waitListAvailable <= 0 
    end 
end 

Les mises en garde pour la liste d'attente sont traitées dans le contrôleur:

if @enrollment.save 
    if @enrollment.confirmed? 
    format.html { redirect_to(@lecture, :notice => 'Enrollment successfull.') } 
    format.xml { render :xml => @lecture, :status => :created, :location => @lecture } 
    else 
    format.html { redirect_to(@lecture, :alert => 'You're on the waiting list!') } 
    format.xml { render :xml => @lecture, :status => :created, :location => @lecture } 
    end