代码之家  ›  专栏  ›  技术社区  ›  Patrick

Rails 3-验证2个模型和附加警告?

  •  0
  • Patrick  · 技术社区  · 14 年前

    我有两种型号:

    • 演讲
    • 注册

    这个讲座有一个容量和一个等候名单。如果有讲课的报名,我想确认是否有空座位。

    为此创建了两个助手:

    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 回复  |  直到 14 年前
        1
  •  1
  •   edgerunner    14 年前

    我假设您的注册模式定义了接受的学生和等待名单上的学生。我还假设讲座模型有两个属性 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 在你的迁移中“等待”。

        2
  •  0
  •   Community Ian Goodfellow    7 年前

    我认为这是最好的处理模式。在我之前提出的一个问题中,我也遇到过类似的问题。

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

        3
  •  0
  •   Patrick    14 年前

    谢谢埃德格伦的回答!我找到了另一个简单的解决方案:

    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