sql - 在 Rails 模型中编写大型 SQL 的更好方法?

标签 sql ruby-on-rails ruby ruby-on-rails-3 coding-style

在使用了很多 Rails 为糖代码提供的 Arel 之后,我遇到了问题 处理大型和复杂的 SQL 查询,而我无法使用 Arel 方法很好地完成它。 我喜欢 Arel 做一些小事,但当它变得凌乱时,我更喜欢分开代码。

那么,对于我应该如何处理模型内部的大型 SQL 有什么建议吗?比如,我什么时候应该为此创建 SQL View (正如我所看到的 Rails 提供的不是很好,我必须为此创建一个迁移)或创建任何单独的类一些文件夹“sqls”,然后从那里调用。

我知道有些人使用<<-SQL 表达式

这是我当前的例子:

Question.from(self.questions
                  .select("questions.id")
                  .select("(NOT (questions.last_active_user_id = #{user.id} OR (COALESCE(ss.updated_at > questions.last_active_at, false) OR COALESCE(ds.updated_at > questions.last_active_at, false))))::integer as active")
                  .select("(((NOT((COALESCE(ss.updated_at > questions.created_at, false) OR COALESCE(ds.updated_at > questions.created_at, false))) AND pages.owner_id = questions.user_id) OR (NOT (COALESCE(ss.updated_at > questions.owner_found_important_at, false) OR COALESCE(ds.updated_at > questions.owner_found_important_at, false)) AND owner_found_important_at is not null AND COALESCE(pages.owner_id <> #{user.id}, true))) AND COALESCE(pages.owner_id <> #{user.id}, true) AND (questions.last_active_user_id <> #{user.id}))::integer as owner_active")
                  .select("COALESCE(COUNT(answers.id) = 0, true)::integer as open")
                  .joins("LEFT JOIN seens ss ON questions.slide_id = ss.viewed_id AND ss.viewed_type = 'Slide' AND ss.viewer_id = #{user.id}")
                  .joins("LEFT JOIN seens ds ON questions.document_id = ds.viewed_id AND ds.viewed_type = 'Document' AND ds.viewer_id = #{user.id}")
                  .joins("INNER JOIN documents ON documents.id = questions.document_id")
                  .joins("INNER JOIN lists ON lists.id = documents.list_id")
                  .joins("INNER JOIN pages ON pages.id = lists.page_id")
                  .joins("LEFT OUTER JOIN answers ON answers.question_id = questions.id")
                  .where("questions.reports_count < 2")
                  .group("questions.id, active, owner_active")
                  .as('questions'))
                  .select("SUM(questions.active) as active, SUM(questions.owner_active) as owner_active, SUM(questions.open) as opened, COUNT(questions.id) as total, SUM(CASE WHEN (questions.active > 0 and questions.open > 0) THEN questions.open ELSE 0 END) as opened_active, SUM(CASE WHEN (questions.owner_active > 0 and questions.open > 0) THEN questions.owner_active ELSE 0 END) as opened_active_owner").first

最佳答案

使用 find_by_sql 而不是结合此处的文档:

Questions.find_by_sql(<<SQL)
select questions.id
  ...
SQL

关于sql - 在 Rails 模型中编写大型 SQL 的更好方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13885040/

相关文章:

sql - 移动平均线/滚动平均线

sql - 对于每个样式的 SQL 查询

MYSQL程序将数据从一个表传输到另一个表

ruby-on-rails - 我如何访问 :locals hash from inside a partial instead of the local variables with the same name?

ruby-on-rails - 在 RSpec 请求规范中使用 Capybara 时,设置自定义请求 header 的最佳方法是什么?

Ruby 中的 Java SecretKeySpec?

ruby - 在 Ruby 中读取输入的最有效方法

sql - 关于案件陈述的问题

javascript - Encodeuricomponent 在 rails 中解码它

ruby - 我将如何获得字符串的这一部分?