dependent: :destroy not working with validates_associated
我一直在使用 uniquness 嵌套属性的两个模型和表单验证。
保存表单时,唯一性验证的范围是列表用户的电子邮件地址。我遇到了一个错误,如果用户尝试在一个事务中保存两封电子邮件,则不会触发验证,因为它会检查数据库中的现有记录,而不是内存中即将保存的对象。
我的模型如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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 |
为了解决这个问题,我添加了:
1 | validates_associated :competitors |
到我的列表模型,当用户尝试为相同的竞争对手保存两个电子邮件地址时,它会导致表单按预期运行,并触发验证。
但是,在运行测试时,我发现此块中的示例现在导致失败。
1 2 3 4 5 6 7 8 | 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
我解决了我自己的问题。在花了几个小时之后,我发现对于失败的测试,有多个,我只需要从测试数据库中重新加载列表。
所以在这个例子中:
1 2 3 | it"deletes associated competitors if the list is deleted" do expect { list.reload.destroy }.to change { Competitor.count }.by(-1) end |
解决了它,以及其他受影响的人。