【问题标题】:Rails 3 - Validation with 2 models and additional warnings?Rails 3 - 使用 2 个模型和其他警告进行验证?
【发布时间】:2011-05-13 02:31:36
【问题描述】:

我有两个模型:

  • 讲座
  • 注册

讲座有名额和等候名单。如果有讲座报名,我想确认是否有空位。

为此创建了两个助手:

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

有什么想法吗?

【问题讨论】:

    标签: ruby-on-rails model-view-controller validation


    【解决方案1】:

    我假设您的注册模型同时定义了被录取的学生和等待名单上的学生。我还假设 Lecture 模型有两个属性 available_seatsavailable_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 的默认值设置为“等待”。

    【讨论】:

      【解决方案2】:

      我认为这在模型中处理得最好。我在之前提出的问题中遇到了类似的问题

      Validating :inclusion in rails based on parent Model's attribute value

      【讨论】:

        【解决方案3】:

        感谢 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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-12-20
          • 1970-01-01
          相关资源
          最近更新 更多