将Mysql查询转换为Rails ActiveRecord查询而不使用find_by_sql

时间:2014-04-18 12:03:46

标签: mysql ruby-on-rails activerecord

我的表格如下命名

+----+---------------------------------------------------------+----------+
| id | title                                                   | category |
+----+---------------------------------------------------------+----------+
| 89 | Tinker or work with your hands?                         |        2 |
| 54 | Sketch, draw, paint?                                    |        3 |
| 53 | Express yourself clearly?                               |        4 |
| 77 | Keep accurate records?                                  |        6 |
| 32 | Efficient?                                              |        6 |
| 52 | Make original crafts, dinners, school or work projects? |        3 |
| 70 | Be elected to office or make your opinions heard?       |        5 |
| 78 | Take photographs?                                       |        3 |
| 84 | Start your own political campaign?                      |        5 |
|  9 | Free spirit or a rebel?                                 |        3 |
| 38 | Lead a group?                                           |        5 |
| 71 | Work in groups?                                         |        4 |
|  2 | Helpful?                                                |        4 |
|  4 | Mechanical?                                             |        6 |
| 14 | Responsible?                                            |        6 |
| 66 | Pitch a tent, an idea?                                  |        1 |
| 62 | Write useful business letters?                          |        5 |
| 28 | Creative?                                               |        3 |
| 68 | Perform experiments?                                    |        2 |
| 10 | Like to figure things out?                              |        2 |
+----+---------------------------------------------------------+----------+

我有一个SQL查询来从每个类别获取一个随机记录。任何人都可以将mysql查询转换为rails activerecord查询(使用Question.find_by_sql)。这个mysql查询工作得很好但我只需要活动记录查询,因为我在后续步骤中依赖。

这是mysql查询

             SELECT t.id, title as question, category
                FROM
              (
                SELECT 
                (
                  SELECT id
                    FROM questions
                   WHERE category = t.category
                   ORDER BY RAND()
                   LIMIT 1
                ) id
                  FROM questions t
                 GROUP BY category
              ) q JOIN questions t
                  ON q.id = t.id

感谢您的考虑!

2 个答案:

答案 0 :(得分:1)

当事情变得疯狂时,我必须伸出Arel

  

它旨在成为一个框架框架;也就是说,你可以建立   你自己的ORM,专注于创新的对象和集合   建模而不是数据库兼容性和查询生成。

所以我们要做的是让Arel为我们创建查询。此外,将使用方法herequestions表与其自身的随机版本保持联系:

q_normal = Arel::Table.new("questions")
q_random = Arel::Table.new("questions").project(Arel.sql("*")).order("RAND()").as("q2")

离开加入的时间

query = q_normal.join(q_random, Arel::Nodes::OuterJoin).on(q_normal[:category].eq(q_random[:category])).group(q_normal[:category]).order(q_random[:category])

现在,您可以使用project来使用您想要的列,例如:

query.project(q_normal[:id])

答案 1 :(得分:0)

我能想到的唯一方法就是需要一些应用程序代码。我认为没有办法使用ActiveRecord访问MySQL中的RAND()功能(或其他数据库技术中的等效功能)。这就是我想出的:

counts = Question.group(:category_id).count(:id)
offsets = {}
counts.each do |cat_id, count|
  offsets[cat_id] = rand(count)
end
random_questions = []
offsets.each do |cat_id, offset|
  random_questions.push(Question.where(:category_id => cat_id).offset(offset).first)
end