mysql - Rails 调查样式应用程序 - 显示选项的所有答案

标签 mysql ruby-on-rails ruby voting vote

我是 ruby​​ on rails 的新手,正在开发我的第一个深入应用程序。它有四个表:问题选项答案用户。有一个问题列表,用户可以投票选出一个独特的选项(存储在 Answers 连接表中),我正在努力了解表关联。

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

我的问题 Controller 是这样设置的,以包含选项表:

@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' - 这是解决这个问题的正确方法吗?我将如何在相关表行下方的表行中输出总票数选项。

我是否需要添加或更改问题 Controller 代码?

这是我的第一篇文章,如果我提供的信息不够多,请见谅!

谢谢

最佳答案

让我们先稍微修复一下关系:

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 足够聪明,可以使用我们的计数器缓存列,但会回退到查询计数,这对测试来说是一件好事。

关于mysql - Rails 调查样式应用程序 - 显示选项的所有答案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35771847/

相关文章:

ruby-on-rails - 键值对的正则表达式 Markdown 字符串

java - Rails 类似于 Java 的数据库抽象

ruby-on-rails - 如何在 simple_form 中使用 select2-rails?

regex - 为什么破折号会扰乱正则表达式搜索?

sql - 在将 select() 与 includes() 和 where() 结合使用时,使用 activerecord 检索虚拟属性

mysql - 我怎样才能得到我的结果 sumOfSalary 的顶级查询

php - 选择不在和在

php - 使用对象的Mysqli连接

php - PDO #1054 'where 子句中的未知列 'n'

ruby-on-rails - 如何按年/月和总和值对 ruby​​ 文字散列进行分组