0

在我的 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>
4

2 回答 2

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方法,它只查看内存中的内容。这很好用。

于 2013-04-23T03:55:07.797 回答
0

验证在包装模型中。因此在保存 Pack Model 时会触发验证。

您需要在 Card 模型的保存中处理此验证。

于 2012-10-13T06:28:00.737 回答