Rails 3 - 使用 2 个模型进行验证并附加警告?

发布于 2024-10-03 08:06:33 字数 732 浏览 1 评论 0原文

我有两种模型:

  • 讲座
  • 报名

讲座有容量和等候名单。如果有讲座报名,我想验证是否有空闲座位。

为此创建了两个助手:

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

有什么想法吗?

I have two models:

  • lecture
  • enrollment

The lecture has a capacity and a waiting list. If there's an enrollment for a lecture, I'd like to validate if there are free seats available.

Created two helpers for that:

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

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

I thought about having the checks in the enrollment-controller, but it doesn't work.

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

Any ideas how this would work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

著墨染雨君画夕 2024-10-10 08:06:33

我假设您的注册模型定义了已接受的学生和候补名单上的学生。我还假设 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 的默认值设置为“waiting”。

I'm assuming that your Enrollment model defines both the accepted students and those on the waiting list. I'm also assuming that the Lecture model has two attributes available_seats and available_wait_space, and the wait list is populated on a first-come basis and students are declined if the list is full, but the actual seats are confirmed or rejected by the lecturer manually.

I'd certainly advise against doing anything at the controller level. This is a job for the models only.

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

By the way, don't forget to set the default value for status to "waiting" in your migrations.

愿与i 2024-10-10 08:06:33

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

根据父模型的属性值验证:包含在轨道中

I think this is best handled in the model. I've had a similar issue in a question I posed previously

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

‖放下 2024-10-10 08:06:33

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

Thanks edgerunner for the answer! I found another, easy solution:

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

The warnings for the waiting list are handled in the controller:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文