Rails 调查样式应用程序 - 显示选项的所有答案
Rails survey style application - Show all answers on option
我是 ruby rails 的新人,正在处理我的第一个深入应用程序。它有四个 table:问题、选项、答案 和用户。有一个问题列表,用户可以投票选出一个独特的选项(存储在答案连接 table 中),我正在努力了解 table 关联。
这是我设置个人 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
我的问题控制器是这样设置的,包括选项 table:
@questions = Question.includes(:options).all
和我的 index.html.erb 文件中的 table 正文:
<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>
在问题 class 中,我使用了 'has_many :answers, :through => :options' - 这是解决这个问题的正确方法吗?我如何在 table 行中输出总票数在相关选项下方。
我是否需要添加或更改问题控制器代码?
这是我的第一个 post,如果我提供的信息不够多,请见谅!
谢谢
让我们先稍微修复一下关系:
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
table关系。
显示计数
如果我们只是这样做:
<td class="optionCell"><%= option.answers.count %></td>
这将创建一个讨厌的 n+1
查询来获取每个选项的答案计数。所以我们想要做的是 create a counter cache 存储选项 table.
的计数
让我们从创建迁移以添加列开始:
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
足够聪明,可以使用我们的计数器缓存列,但会回退到查询计数,这对测试来说是一件好事。
我是 ruby rails 的新人,正在处理我的第一个深入应用程序。它有四个 table:问题、选项、答案 和用户。有一个问题列表,用户可以投票选出一个独特的选项(存储在答案连接 table 中),我正在努力了解 table 关联。
这是我设置个人 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
我的问题控制器是这样设置的,包括选项 table:
@questions = Question.includes(:options).all
和我的 index.html.erb 文件中的 table 正文:
<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>
在问题 class 中,我使用了 'has_many :answers, :through => :options' - 这是解决这个问题的正确方法吗?我如何在 table 行中输出总票数在相关选项下方。
我是否需要添加或更改问题控制器代码?
这是我的第一个 post,如果我提供的信息不够多,请见谅!
谢谢
让我们先稍微修复一下关系:
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
table关系。
显示计数
如果我们只是这样做:
<td class="optionCell"><%= option.answers.count %></td>
这将创建一个讨厌的 n+1
查询来获取每个选项的答案计数。所以我们想要做的是 create a counter cache 存储选项 table.
让我们从创建迁移以添加列开始:
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
足够聪明,可以使用我们的计数器缓存列,但会回退到查询计数,这对测试来说是一件好事。