在我的Rails应用程序中,我有Card和Pack模型,以及它们之间的多对多关系。我想验证一个包中是否正好有3张卡片。该包使用复选框实现与卡相关联。
我的问题:运行验证时,似乎没有关联。验证失败,打印输出为“卡计数为:0”。为什么验证运行时没有关联? (注意:当删除验证时,关联是正确的,因此代码可以工作,而不是验证)
# Pack Model
class Pack < ActiveRecord::Base
has_many :pack_elements
has_many :cards, :through => :pack_elements
validate :validate_number_of_cards
def validate_number_of_cards
puts "cards count is: " + cards.count
errors.add(:cards, "A pack must contain exactly 3 cards.") if (cards.count != 3)
end
end
其他模型正如您所期望的那样,但没有验证。这是Packs表单,它显示所有卡片,每个卡片旁边都有一个复选框,还有一个提交按钮。我想测试一下这些盒子中有三个被检查了,我希望测试在模型中,而不是在表格中。
# packs/_form.html.erb
<%= form_for(@pack) do |f| %>
<div class="field">
<% @cards.each do |card| %>
<%= hidden_field_tag "pack[card_ids][]", nil %>
<%= check_box_tag "pack[card_ids][]", card.id, @pack.card_ids.include?(card.id), id: dom_id(card) %>
<%= label_tag dom_id(card), card.description %>
<hr/>
<% end %>
</div>
<div class="actions">
<%= f.submit %>
</div>
答案 0 :(得分:3)
上面实现的问题是我使用的是 count 方法,它进行数据库查找。在验证通过之前,数据库不会保存,因此永远不会起作用。我将实现更改为:
def validate_number_of_cards
puts "Count shows there are " + cards.count + " cards." # always returns zero
puts "Size shows there are " + cards.size + " cards."
errors.add(:cards, "A pack must contain exactly 3 cards.") if (cards.size != 3)
end
使用 size 方法,它只是查看内存中的内容。这很好。
答案 1 :(得分:0)
验证在Pack Model中。因此,在保存包模型时会触发验证。
您需要在保存卡片模型时处理此验证。