我有一个有许多LoggedTimes的Task。我想在任何一天对任务设置8小时的记录时间限制。最好的方法是什么,以便我可以检查一个人的最新记录时间是否“超过限制”一天,可以这么说?
这是我开始的地方(Task.rb):
validate :max_logged_daily_time
def max_logged_daily_time
if (params[:session_time] + (logged_times.where(:created_at => Date.today).to_a.sum(&:session_time)/60)) > 8
errors.add_to_base("Can't have more than 8 hours logged a day")
logged_time.errors.add('session_time', 'Logged times exceeded today')
end
end
目前这个验证无效(添加另一个LoggedTime,一旦注册了8个小时的先前记录时间,只需将其添加到其余部分,而不是抛出错误。由于没有抛出错误,我很难选择我的解决问题的方法。是否与处理params有关?
这让我想到了设计问题:理论上我可以修改视图,这样用户只能提交8小时减去他们当天记录的总时间;然而,这似乎是一个笨重的解决方案,并且违背了在模型中保持验证的原则。 (它肯定无法帮我解决这个模型验证问题)。
这里有什么建议吗?
TIA
答案 0 :(得分:1)
我会创建一个单独的方法来获取给定日期的小时数。
def total_hrs_logged_for_date(date)
#some code
end
测试该方法以确保其有效。
可能也会计算当前记录的时间。
然后在自定义验证器中使用那两个
所以这一行
if (params[:session_time] + (logged_times.where(:created_at => Date.today).to_a.sum(&:session_time)/60)) > 8
变为
if total_hrs_logged_for_date(Date.today) + current_time_being_logged > 8
至少它会帮助你缩小哪些不起作用。
我还注意到你有“params [:session_time]”
我认为这是在Task.rb中,这听起来像一个模型。可能你想要的只是“session_time”而已。
答案 1 :(得分:1)
class Task < ActiveRecord::Base
has_many :logged_times
def hours_today
LoggedTime.daily_hours_by_task(self).to_a.sum(&:session_time)
end
end
class LoggedTime < ActiveRecord::Base
belongs_to :task
scope :daily_hours_by_task, lambda { |task| task.\
logged_times.\
where('logged_times.created_at >= ? AND logged_times.created_at < ?',
Date.today, Date.today + 1) }
validate :max_logged_daily_time
private
def max_logged_daily_time
if task && ((task.hours_today + session_time) / 60.0) > 8
errors.add('session_time', 'Logged times exceeded today')
end
end
end
一些注意事项:
created_at
是一个DateTime,所以你会
需要测试开始和结束
当天
验证也会阻止 添加单个LoggedTime,它本身超过了最大值。
除以整数截断和
会给出错误的结果 - 添加
.0
转换为浮动。
这只验证LoggedTime,
不是任务,所以你可能想要
添加validates_associated
任务模型。
当Task为nil时,绕过验证
修改强>
嗯,hours_today
应该被称为minutes_today
,但你明白了。
答案 2 :(得分:0)
我最后稍微修改了Zetetic的回复,因为我无法让它按原样运行。
最后,这有效:
class Task < ActiveRecord::Base
has_many :logged_times
validates_associated :logged_times
def minutes_today
logged_times.where('created_at >= ? AND created_at < ?', Date.today, Date.today + 1)
end
end
和LoggedTime模型:
class LoggedTime < ActiveRecord::Base
belongs_to :task
validate :max_logged_daily_time
private
def max_logged_daily_time
if task && ((task.minutes_today + session_time) / 60.0) > 8
errors.add('session_time', 'Logged times exceeded today')
end
end
end
我不确定范围方法为什么会阻止,但确实如此。任何提示Zetetic?