Проверка модели Rails на количество отношений has_many

В моем приложении 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/_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>

person joseph.hainline    schedule 13.10.2012    source источник
comment
Вы решили эту проблему? Так как у меня есть похожий, и я не могу найти ответ.   -  person Marcin Doliwa    schedule 23.04.2013
comment
@MarcinDoliwa Я решил это, см. ответ ниже.   -  person joseph.hainline    schedule 23.04.2013


Ответы (2)


Проблема в приведенной выше реализации заключается в том, что я использовал метод 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, который просто смотрит, что находится в памяти. Это прекрасно работает.

person joseph.hainline    schedule 23.04.2013

Проверка проводится в Pack Model. поэтому проверка запускается при сохранении модели пакета.

Вам нужно обработать эту проверку в сохранении модели карты.

person Manjunath Manoharan    schedule 13.10.2012
comment
Как мне проверить, сколько карт в наборе из модели карт? Я не вижу способа сделать это. - person joseph.hainline; 13.10.2012