0

可能是某种特定的情况。而且我有点知道如何在 PHP/MySQL 中做到这一点。但我想知道是否有更快的方法来执行以下场景:

用户的活动具有开始日期和结束日期。(例如,活动从 2013 年 12 月 10 日 12:00:00 开始,到 2013 年 12 月 10 日 12:15:00 结束。)

每当用户创建新活动时。我想检查用户参与的所有活动(用户has_many: activities),看看是否没有任何日期与为新活动指定的日期相交。

由于我对 Rails 还很陌生,我真的不知道从哪里开始搜索日期比较和所有...

提前致谢

4

3 回答 3

1

重叠定义为结束日期大于或等于新活动开始日期且开始日期小于或等于新活动结束日期的另一活动。

由于您只想检测这样的记录是否已经存在,因此适当的测试是:

if Activity.where("starts_at <= ?" , new_activity_end_date  ).
            where("ends_at   >= ?" , new_activity_start_date).
            exists?
于 2013-10-28T13:07:26.333 回答
0

You can use regular comparators for date/times in Ruby (ie: >, < and ==).

Something like the following should do what you are looking for:

if current_user.activities.where("(starts_at <= ? AND ends_at >= ?) OR (starts_at >= ? AND starts_at <= ?)", start_datetime, start_datetime, start_datetime, end_datetime).count
  # There exist activities that fall between start_datetime and end_datetime
else
  # There exist no such activities
end

(starts_at <= start_datetime AND ends_at >= start_datetime) checks whether an event starts before and ends after start_datetime.

(starts_at >= start_datetime AND starts_at <= end_datetime) checks whether an event starts between start_datetime and end_datetime.

于 2013-10-28T12:56:00.217 回答
0

我们必须检查所有这三种交集都不会发生:

  • 我们的活动不得发生在另一个活动中
  • 我们的活动不能在另一个结束之前开始
  • 我们的活动不能在另一个开始后结束

我们可以使用这样的方法来做到这一点:

class Activity < ActiveRecord::Base

  validate :must_not_be_intersected

  def intersected?
    params = {
      :start => start_date,
      :end => end_date
    }

    Activity::where('start_date <= :start AND end_date >= :end', params)
      .where('(start_date >= :start AND start_date <= :end) OR (end_date >= :start AND end_date <= :end)', params)
      .exists?
  end

private

  def must_not_be_intersected
    errors.add :base, 'Other task running on the same period' if intersected?
  end

end
于 2014-03-24T18:15:37.343 回答