Validates_Overlap:'条件范围'?

时间:2014-10-26 04:24:03

标签: ruby-on-rails ruby validation ruby-on-rails-4

我问了一个关于带有验证重叠here的范围的问题,但这个问题使代码更进了一步,并且有一个涉及条件范围的不同问题(可能被称为其他东西)

我的应用程序的简要概要(也在其他问题中描述)。我正在创建一个预订应用程序,并使用验证重叠宝石,我想确保同一房间的预订没有重叠。有两个房间。他们都可以同时预订。

到目前为止解决其他问题,目前的代码如下:

class Booking < ActiveRecord::Base
  scope :confirmed_scope, -> {confirmed: true}  
  validates :start_time, :end_time, :overlap => {
    :exclude_edges => ["starts_at", "ends_at"],
    :scope => "studio_id",
    :query_options => {:confirmed_scope => nil}
    }, on: :update
end

感谢Robin Bortlik帮助我弄清楚这个范围。

在此代码中,无法同时预订房间。

虽然仍存在一个问题,工人和客户仍然可以同时预订两个房间,这是不理想的(因为很明显,人们不能同时在两个地方)。客户和工人不会故意预订两次,但我觉得将其用于验证以确保工人不会意外地与两个不同的客户预订(在两个不同的房间,这个是可能的)

由于上面没有使用worker_id或client_id进行检查,因此只有在该房间可用时才允许预订。它不在乎谁在预订。

我需要添加一个'条件范围'来检查正在预订的client_id或worker_id是否已经同时在OTHER房间预订。

我尝试了以下代码:

:scope => ["studio_id","worker_id","client_id"], {...}

但是,如果THAT工作室预订了THAT工作人员,并且允许重复预订THAT工作室,那么现在只会标记验证。

理想情况下,预订仅在房间可用时才会通过,如果是,请检查以确保当前预订的工人在另一个房间预订。 如何更改我的范围以检查上述情况?

希望我的问题很明确,如果有任何不清楚或需要更多信息,请告诉我。 更新:我认为Robin提供的解决方案几乎就是我所需要的,但是将studio_id保持在原来的位置,并将工作者和客户端ID包含在一个单独的范围内。

这样的代码让我得到一个参数错误1为2:

scope :includes_studio_worker_client, -> (client_id, engineer_id) { where('engineer_id = ? OR client_id = ?', engineer_id, client_id) }
validates :start_time, :end_time, :overlap => {
            :scope => "studio_id",
            :query_options => {
                :confirmed_scope => nil,
                :includes_studio_worker_client => 
                    proc{ |booking| [booking.engineer_id, booking.client_id] }
                },
            :exclude_edges => ["start_time", "end_time"]
        }

1 个答案:

答案 0 :(得分:2)

更新: 我想,我现在明白你的问题。你需要的是不搜索在时间上重叠并具有相同“studio_id”AND“worker_id”和“client_id”的条目。但是您需要搜索时间重叠且具有相同“studio_id”或“worker_id”或“client_id”的条目。是不是?

您将作为:scope选项传递的所有内容将与“AND”连接。所以你需要为每个属性编写验证。

结果代码如下所示:

class Booking < ActiveRecord::Base
    scope :confirmed, -> {where(confirmed: true)}

    validates :starts_at, :ends_at, :overlap => {
      :exclude_edges => ["starts_at", "ends_at"],
      :query_options => {:confirmed => nil},
      :scope => 'client_id',
      :message_content => 'is already taken in this time',
      :message_title => 'Client '
    }, on: :update

    validates :starts_at, :ends_at, :overlap => {
      :exclude_edges => ["starts_at", "ends_at"],
      :query_options => {:confirmed => nil},
      :scope => 'worker_id',
      :message_content => 'is already taken in this time',
      :message_title => 'Worker '
    }, on: :update

    validates :starts_at, :ends_at, :overlap => {
      :exclude_edges => ["starts_at", "ends_at"],
      :query_options => {:confirmed => nil},
      :scope => 'studio_id',
      :message_content => 'is already taken in this time',
      :message_title => 'Studio '
    }, on: :update
end

BTW ..这里是如何在rails 4 scopes with lambda and arguments in Rails 4 style?

中编写范围