【发布时间】:2016-08-25 23:41:01
【问题描述】:
我创建了一个模型:Lecture(start_time, end_time, location)。我想编写验证函数来检查新讲座的时间是否与数据库中保存的讲座重叠。这样我就可以知道那个位置是否在那个时候被占用。我的功能是:
class Lecture < ActiveRecord::Base
validates :title, :position, presence: true
validates :start_time, :end_time, format: { with: /([01][0-9]|2[0-3]):([0-5][0-9])/,
message: "Incorrect time format" }
validate: time_overlap
def time_overlap
Lecture.all.each do |user|
if (user.start_time - end_time) * (start_time - user.end_time) >= 0
errors.add(:Base, "time overlaps")
end
end
end
end
错误信息:LecturesController#create 中的 NoMethodError nil:NilClass 的未定义方法“-@”。这个函数怎么写成正确的格式?
【问题讨论】:
-
您提到您的控制器出现错误,但仍未添加控制器代码??
-
您在
lectures_controller.rb的create方法中有错字(顺便说一句,您忽略了发布)。撇开这一点不谈,你处理时间冲突的方法是低效的。与其从数据库中加载所有讲座并在 Ruby 中进行比较,不如构建一个查询来选择具有 start_time new_lecture.end_time 的讲座。不要在应用程序代码中做你的数据库可以为你做的事情。 -
控制器在没有 time_overlap 函数的情况下工作正常,我只是不明白在这种情况下 ''undefined method `-@' for nil:NilClass" 是什么。我猜我在 time_overlap 中的代码有错误的 ruby 样式。希望知道如何检查时间是否与正确的代码重叠。
-
-@是一种方法:尝试输入1.send(:-@)。它代表否定。现在尝试输入nil.send(:-@)。在某处你有一个 nil 值,可能是 start_time 或 end_time,试图被否定。也尝试输入Time.zone.now - nil。这应该会引导您朝着正确的方向前进。 -
@runchu 我会支持将过滤移动到数据库中的建议,特别是因为每次保存讲座对象都会运行。您也可以仅在创建时或开始或结束时间更改时验证这种方式。不过,无论如何,@MarsAtomic 你的效率是对的,但你的查询不包括所有可能的重叠讲座。我会使用已经编写的逻辑来输入查询:
Lecture.where("(lectures.start_time - ?) * (? - lectures.end_time) >= 0", self.end_time, self.start_time).present?
标签: ruby-on-rails ruby model