sql >> Databasteknik >  >> RDS >> Mysql

Rails undersökning stil applikation - Visa alla svar på alternativet

Låt oss börja med att fixa till relationerna lite:

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

Det är inget tekniskt fel med has_many :answers, :through => :options men eftersom det finns en direkt relation genom answers.question_id vi behöver inte gå igenom options tabell för relationen.

Visar antalet

Om vi ​​helt enkelt gjorde:

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

Detta skulle skapa en otäck n+1 fråga för att hämta antalet svar för varje alternativ. Så vad vi vill göra är att skapa en räknarcache som lagrar en sammanställning på alternativtabellen.

Låt oss börja med att skapa en migrering för att lägga till kolumnen:

rails g migration AddAnswerCounterCacheToOptions answers_count:integer
rake db:migrate

Sedan säger vi till ActiveRecord att uppdatera sammanräkningen när vi skapar associerade poster, detta ser lite konstigt ut eftersom counter_cache: true deklarationen finns på belongs_to sidan medan kolumnen är på den andra men det är precis så AR fungerar.

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

Det finns en liten hake här. Eftersom vi kanske redan har poster måste vi se till att de har korrekta räknare. Du kan göra detta från konsolen men i det långa loppet är det en bra idé att skapa en rake-uppgift .

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

Detta kan ta lite tid eftersom det måste dra varje alternativ och uppdatera antalet.

Nu kan vi visa sammanräkningen så här:

<% 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 är smart nog att använda vår räknarcache-kolumn, men kommer att falla tillbaka till att fråga efter räkningen, vilket är bra för tester.




  1. Det går inte att ansluta google apps script till mysql via localhost

  2. Hur skapar man ett ja/nej booleskt fält i SQL-servern?

  3. Hur Oracle Index klustringsfaktor beräknas

  4. Postgres utlöser checkbeloppet innan radering