Ruby on rails 在rails 6上未触发保存回调之前
运行测试时:Ruby on rails 在rails 6上未触发保存回调之前,ruby-on-rails,Ruby On Rails,运行测试时: 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(ta
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
将触发前保存回调,如图所示:
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\u validation的地方粘贴了较旧版本的代码。调用before\u save回调。尝试在方法中添加调试器,请参见!但它并没有做你想做的事情——你的代码中有一个bug
要修复代码,如果检查失败,则需要添加验证错误。您当前的方法只是检查任务是否存在;它实际上对这些信息没有任何作用
你可以这样写:
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',其作用域为:
或者,如果您愿意,也可以将其转换为一行代码:
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
然后还可以验证重复任务被视为无效的原因。此外,您可能希望考虑使用A来创建记录,而不是直接使用Rails类。非常感谢!我会采纳你的建议。
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