Rails 3 - валидация с 2 моделями и дополнительные предупреждения? - PullRequest
0 голосов
/ 20 ноября 2010

У меня есть две модели:

  • лекция
  • регистрация

Лекция имеет вместимость и список ожидания.Если есть запись на лекцию, я хотел бы проверить, есть ли свободные места.

Для этого создано два помощника:

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

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

Я думал о том, чтобы иметь чеки вконтроллер регистрации, но он не работает.

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

Есть идеи, как это будет работать?

Ответы [ 3 ]

1 голос
/ 20 ноября 2010

Я предполагаю, что ваша модель зачисления определяет как принятых, так и тех, кто находится в списке ожидания.Я также предполагаю, что модель лекции имеет два атрибута available_seats и available_wait_space, и список ожидания заполняется в порядке поступления, и студенты отклоняются, если список заполнен, но фактические места подтверждены или отклоненылектором вручную.

Я бы, конечно, не советовал ничего делать на уровне контроллера.Это задание только для моделей.

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

Кстати, не забудьте установить значение по умолчанию для status на "ожидание" в ваших миграциях.

0 голосов
/ 20 ноября 2010

Спасибо edgerunner за ответ! Я нашел другое, простое решение:

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

Предупреждения для списка ожидания обрабатываются в контроллере:

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
0 голосов
/ 20 ноября 2010

Я думаю, что это лучше всего обрабатывается в модели. У меня была похожая проблема в вопросе, который я поставил ранее

Проверка: включение в рельсы на основе значения атрибута родительской модели

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...