【问题标题】:rails - manipulate datetime data before_updaterails - 在更新前操作日期时间数据
【发布时间】:2013-12-22 16:24:04
【问题描述】:

我有两个模型:计划和任务。 Task belongs_to Schedule 和 Schedule has_many 任务。任务的形式是计划的嵌套形式。我正在尝试编写控制器代码或模型方法,将用户输入的日期时间(称为:time_frame)用于任务,如果该日期时间已经发生(过去),将发出通知并重定向。我已经尝试过几种方法,但没有一种方法有效。我尝试为 schedules#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

'before task is found' 被放到服务器上,但是其他两个 put 都没有被执行。我该怎么做?

【问题讨论】:

    标签: ruby-on-rails oop datetime model-view-controller ruby-on-rails-4


    【解决方案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 与 datetime 进行比较之前没有解析它,您应该这样做:

    if DateTime.parse(task[:time_frame]) < DateTime.now
      # code here ...
    

    这是因为控制器看到的是原始字符串形式的 time_frame 值。当您将其分配给您的任务时,activerecord 会将其转换为日期时间列的数据类型(我假设您在迁移中以这种方式设置)。

    更新: 关于你得到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
    

    当然,任务模型的验证是解决这个问题的更好方法。

    【讨论】:

    • 谢谢,我尝试了 validate 方法,但如果 time_Frame 为空,它会返回错误 'undefined method `
    • 如果您要求 time_frame 始终存在,请在 datetime_in_future 验证器之前添加一个存在验证器。我会用这个更新我的答案。
    • 谢谢。关于控制器,它仍然返回相同的无符号到字符串的隐式转换错误?
    • 我会用那个解决方案更新我的答案,我之前错过了一些东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-15
    • 2017-04-22
    • 2012-05-14
    • 1970-01-01
    • 1970-01-01
    • 2013-03-30
    • 1970-01-01
    相关资源
    最近更新 更多