2016-03-03 171 views
2

我是一個在軌道上進行紅寶石並開始我的第一個深入應用程序的新人。它有四個表格:問題,選項,答案用戶。有一個問題列表,用戶可以投票選擇一個獨特的選項(存儲在Answers連接表中),我試圖讓我的表頭關聯到表關聯。Rails調查樣式應用程序 - 在選項上顯示所有答案

This is an example of how I'm using the database, minus the Survey and Survey Question

這是我已經設置我的個人RB文件:

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

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

class Answer < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :question 
    belongs_to :option 
end 

class User < ActiveRecord::Base 
    has_many :answers 
    has_many :questions, :through => :answers 
end 

我的問題控制器設置像這樣包含的選項表:

@questions = Question.includes(:options).all 

和我的index.html.erb文件中的表體:

<tbody> 
    <% @questions.each do |question| %> 
     <tr class="<%= cycle('lineOdd', 'lineEven') %>"> 
     <td><%= question.question_text %></td> 
     <td><%= link_to 'Show', question %></td> 
     <td><%= link_to 'Edit', edit_question_path(question) %></td> 
     <td><%= link_to 'Destroy', question, method: :delete, data: { confirm: 'Are you sure?' } %></td> 
     </tr> 
     <% question.options.each do |option_text| %> 
     <tr class="backgroundColor1"> 
      <td class="optionCell"> <%= option_text.option_text %> </td> 
     </tr> 
     <% end %> 
    <% end %> 
</tbody> 

在Question類中,我使用了'has_many:answers,:through =>:options' - 這是正確的方法,我將如何輸出關聯下的表格行中的總票數選項。

是否需要添加或更改問題控制器代碼?

這是我的第一篇文章,對不起,如果我沒有足夠的信息!

感謝

+0

真的令人耳目一新,看到第一個問題很好,但包括所有相關信息。做得好。 – max

+0

啊謝謝 - 我現在非常享受Rails,所以我希望能夠堅持下去! – classequalsarthur

回答

1

讓我們通過固定起來的關係有點開始:

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

沒有什麼技術上的錯誤與has_many :answers, :through => :options但因爲有直接的關係,通過answers.question_id我們並不需要經過該關係的表格爲options

顯示計數

如果我們壓根兒:

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

這將創建一個討厭的n+1查詢來獲取答案,每個選項的數量。所以我們想要做的是create a counter cache,它在選項表上存儲一個標籤。

讓我們通過創建一個遷移添加列開始:

rails g migration AddAnswerCounterCacheToOptions answers_count:integer 
rake db:migrate 

然後我們告訴ActiveRecord的更新當我們創建相關記錄理貨,因爲counter_cache: true聲明是在belongs_to側這看起來有點怪而專欄是另一個,但多數民衆贊成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 

這裏有一個小障礙。由於我們可能已經有記錄,因此我們需要確保他們有正確的計數器。您可以從控制檯執行此操作,但從長遠來看,create a rake task是個好主意。

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

這可能需要一些時間,因爲它需要拉動每個選項並更新計數。

現在我們可以顯示理貨像這樣:

<% 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是足夠聰明的使用我們的櫃檯緩存列,但會回落到查詢這是試驗一件好事計數。

+0

'counter_cache'的替代方法是編寫一個select子句,它在子查詢中提取計數。由於您確實需要了解ActiveRecord如何構建查詢和加載關係,因此不推薦給初學者。 – max

+0

非常感謝,真的很有用! :-) – classequalsarthur

相關問題