[英]before_save callback is not being triggered on rails 6
在运行测试时:
require 'rails_helper'
RSpec.describe DailyTask, type: :model do
context 'crud' do
[...]
end
context 'validations' do
let(:task) { create(:task) }
it 'duplicated task, fails' do
2.times do
DailyTask.create(task: task, date: Date.today)
end
expect(DailyTask.count).to eq(1)
end
end
end
将触发before_save
回调,如下所示:
class DailyTask < ApplicationRecord
belongs_to :task
validates_presence_of :date
before_save :is_there_a?
def is_there_a?
DailyTask.where(date: self.date, task_id: self.task_id).empty?
end
end
然而,它似乎没有被触发。 已经尝试将其更改为before_validation
无济于事。 这是一种愚蠢的错误,除非有人指出,否则您不会看到。
编辑:在调用before_validation
地方粘贴了旧版本的代码。
该before_save
回调被调用。 (尝试在方法中添加调试器,然后看看!)但它并没有按照您的意愿行事 - 您的代码中存在错误。
要修复代码,如果检查失败,您需要添加验证错误。 (您当前的方法只是检查任务是否存在;它实际上并没有对这些信息做任何事情。)
你可以这样写:
validate :is_there_a?
def is_there_a?
if DailyTask.where(date: self.date, task_id: self.task_id).any?
errors.add(:date, 'already exists for this task')
end
end
或者,您可以只使用 Rails 的内置唯一性验证方法,其范围为:
validate_uniqueness_of :date, scope: :task_id
或者,如果您愿意,也可以将两个验证规则合并到一行代码中:
validates :date, presence: true, uniqueness: { scope: :task_id }
作为一个单独的建议,我个人会以稍微不同的方式编写这个测试。 代替:
it 'duplicated task, fails' do
2.times do
DailyTask.create(task: task, date: Date.today)
end
expect(DailyTask.count).to eq(1)
end
您可以考虑编写它以更明确地测试验证:
it 'duplicated task, fails' do
DailyTask.create(task: task, date: Date.today)
duplicate_daily_task = DailyTask.new(task: task, date: Date.today)
expect(duplicate_daily_task).not_to be_valid
end
然后,您还可以验证为什么重复任务被视为“无效”。 此外,您可能希望考虑使用工厂来创建记录,而不是直接使用 rails 类。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.