我一直在使用两个模型,并在嵌套属性上形成单一的验证。
保存表单时,唯一性验证的范围限定为列表用户的电子邮件地址。我遇到了一个错误,如果用户试图在一个事务中保存两封电子邮件,则不会触发验证,因为它会检查数据库中的现有记录,而不是内存中即将保存的对象。
我的模型如下:
class List < ActiveRecord::Base
has_many :competitors, dependent: :destroy, inverse_of: :list
accepts_nested_attributes_for :competitors, reject_if: :all_blank, allow_destroy: true
end
class Competitor < ActiveRecord::Base
belongs_to :list, inverse_of: :competitors
validates :list, presence: true
validates :name, presence: true, length: { minimum: 2, maximum: 20 }
validates :email, presence: true, format: { with: User::EMAIL_REGEX }
validates :email, uniqueness: { scope: :list_id }
end
为了解决这个问题,我补充道:
validates_associated :competitors
到我的列表模型,它现在导致表单按预期运行,当用户尝试为竞争对手保存两个电子邮件地址时,验证将被关闭。
然而,运行我的测试,我发现此块中的示例现在导致失败。
describe "@competitors" do
let!(:list) { FactoryGirl.create(:list) }
let!(:competitor) { FactoryGirl.create(:competitor, list_id: list.id) }
it "deletes associated competitors if the list is deleted" do
expect { list.destroy }.to change { Competitor.count }.by(-1)
end
end
到目前为止,我的研究告诉我,这不是一个常见的问题,所以我认为我做错了什么,但我不能说出那是什么。
我使用的是ruby 2.3.0和rails 4.2.7.1
答案 0 :(得分:1)
我解决了自己的问题。花了好几个小时后,我得出结论,对于失败的测试,有多个,我只需要从测试数据库重新加载列表。
所以在这个例子中:
it "deletes associated competitors if the list is deleted" do
expect { list.reload.destroy }.to change { Competitor.count }.by(-1)
end
解决了它,以及受影响的其他人。