sql >> Databáze >  >> RDS >> Mysql

Aplikace ve stylu průzkumu kolejí - Zobrazit všechny odpovědi na možnost

Začněme tím, že trochu upravíme vztahy:

class Question < ActiveRecord::Base
  has_many :options
  has_many :answers
  has_many :users, through: :answers
end

Na has_many :answers, :through => :options není technicky nic špatného ale protože existuje přímý vztah prostřednictvím answers.question_id nemusíme procházet options tabulka pro vztah.

Zobrazení počtu

Kdybychom to prostě udělali:

<td class="optionCell"><%= option.answers.count %></td>

Vzniklo by ošklivé n+1 dotaz k načtení počtu odpovědí pro každou možnost. Chceme tedy vytvořit mezipaměť počítadel který ukládá součet v tabulce možností.

Začněme vytvořením migrace pro přidání sloupce:

rails g migration AddAnswerCounterCacheToOptions answers_count:integer
rake db:migrate

Poté řekneme ActiveRecord, aby aktualizoval záznam, když vytváříme související záznamy, vypadá to trochu divně, protože counter_cache: true deklarace je na belongs_to straně, zatímco sloupec je na druhé, ale přesně tak funguje AR.

class Option < ActiveRecord::Base
  belongs_to :question
  has_many :answers
end

class Answer < ActiveRecord::Base
  belongs_to :user
  belongs_to :question
  belongs_to :option, counter_cache: true
end

Je zde malý zádrhel. Protože možná již máme záznamy, musíme se ujistit, že mají správná počítadla. Můžete to udělat z konzole, ale z dlouhodobého hlediska je dobrý nápad vytvořit úlohu rake .

Option.find_each { |option| Option.reset_counters(option.id, :answers) }

To může chvíli trvat, protože je třeba stáhnout každou možnost a aktualizovat počet.

Nyní můžeme zobrazit součet takto:

<% question.options.each do |option| %>
  <tr class="backgroundColor1">
    <td class="optionCell"><%= option.option_text %></td>
    <td class="optionCell"><%= option.answers.size %></td>
  </tr>
<% end %>

.size je dostatečně chytrý na to, aby používal náš sloupec mezipaměti počítadel, ale vrátí se k dotazování na počet, což je dobrá věc pro testy.




  1. SQL select where not in subdotaz nevrací žádné výsledky

  2. Nejlepší způsob, jak vytvořit koncový bod SPARQL pro RDBMS (databáze MySQL)

  3. Ruby on Rails MySQL #08S01Špatný handshake – downgrade MySQL?

  4. Migrace z Oracle na PostgreSQL – co byste měli vědět