我有两个模型:Schedule和Task。任务belongs_to计划和安排has_many任务。任务表单是Schedule的嵌套形式。我正在尝试编写控制器代码或模型方法,它将为用户输入用户输入的日期时间(称为:time_frame),如果该日期时间已经发生(过去),则会吐出通知并重定向。我尝试过这几种方法,但都没有奏效。我尝试为计划#update:
编写这个控制器代码schedule_params[:tasks_attributes].each do |task|
if task[:time_frame] < DateTime.now
render 'update', :notice => 'You must pick a future time.'
end
end
这是schedule_params:
def schedule_params
params.require(:schedule).permit(:emp_accepts,
tasks_attributes: [:title, :content, :_destroy, :time_frame,
:complete_time])
end
但是我收到了错误:
no implicit conversion of symbol to integer
我尝试在Schedule模型中编写这样的模型方法:
before_update :compare_datetimes
def compare_datetimes
puts 'before task is found'
self.tasks.each do |task|
puts 'here is the task'
if task.time_frame < DateTime.now
puts 'It is in the past'
end
end
end
在找到任务之前'被放入服务器,但是其他两个放置都没有被执行。我该怎么做?
答案 0 :(得分:1)
您希望在保存之前向任务模型添加验证以检查time_frame:
class Task < ActiveRecord::Base
validate :time_frame, presence: true # if you require time_frame to always be present
validate :datetime_in_future
private
def datetime_in_future
# if time_frame is optional, check its presence before comparing
if !self.time_frame.blank? && self.time_frame < DateTime.now
errors.add :time_frame, 'must be a future time.'
end
end
end
当您保存或更新时,这会使您的关联失效,从而使计划无效。
关于你的控制器:不起作用的原因是你没有解析time_frame,然后将它与日期时间进行比较,你应该这样做:
if DateTime.parse(task[:time_frame]) < DateTime.now
# code here ...
这是因为控制器以原始字符串形式查看time_frame值。当您将其分配给您的任务时,activerecord会将其转换为datetime列的数据类型(我假设您在迁移中将其设置为这样)。
<强>更新强>
关于控制器错误,你得到no implicit conversion of symbol to integer
tasks_attributes
是一个索引哈希,所以你需要像这样迭代它:
schedule_params[:tasks_attributes].each_pair do |index, task|
if task[:time_frame] < DateTime.now
render 'update', :notice => 'You must pick a future time.'
end
end
但是,当然,任务模型的验证是解决这个问题的更好方法。