【问题标题】:Rails order by sum of two association's columnsRails 按两个关联列的总和排序
【发布时间】:2021-12-07 03:09:39
【问题描述】:
class Question < ApplicationRecord
  has_many :question_articles
  has_many :articles, through: :question_articles
end
class Article < ApplicationRecord
  has_many :question_articles
  has_many :questions, through: :question_articles
end
class QuestionArticle < ApplicationRecord
  belongs_to :article
  belongs_to :question
end

question_articles 表包含 2 列:user_usages_countadmin_usages_count

我需要检索由question_articles.user_usages_count + question_articles.admin_usages_count 排序的questions

我试过了:

Question  
  .joins(:articles)
  .includes(:question_articles)
  .order('question_articles.admin_usages_count + question_articles.user_usages_count DESC')

但我收到了'disallow_raw_sql!': Query method called with non-attribute argument

【问题讨论】:

  • 您的实际问题是什么?是否有意外结果或错误?错误信息是什么样子的?

标签: ruby-on-rails ruby activerecord


【解决方案1】:

要解决 'disallow_raw_sql!': Query method called with non-attribute argument 的问题,我们需要使用 build in Arel.sql 方法

所以可行的解决方案是

Question  
  .joins(:articles)
  .includes(:question_articles)
  .order(Arel.sql('question_articles.admin_usages_count + question_articles.user_usages_count DESC'))

【讨论】:

    【解决方案2】:

    您应该能够完全避免引用 SQL 并将您的逻辑保留在 ruby​​ 中,方法是在您的 Question 模型中创建一个看起来像这样的方法(假设您需要来自所有相关 QuestionArticle 的这两个字段的总数记录)。

    def self.by_usage
      all.sort_by do |_question|
        _question.question_articles.reduce(0) { |_sum, _qa| _sum += (_qa.user_usages_count + _qa.admin_usages_count) }
      end
    end
    

    然后您应该能够使用@questions.by_usage 并取回按每个问题的相关 QuestionArticle 记录中所有使用次数的总和排序的问题记录。

    假设这满足您的需要,您可以通过向 QuestionArticles 模型添加一个返回这两个字段总和的方法来进一步整理它:

    def total_usage
      user_usages_count + admin_usages_count
    end
    

    reduce 行将简化为:

    _question.question_articles.reduce(0) { |_sum, _qa| _sum += _qa.total_usage }
    

    这本身就简化为:

    _question.question_articles.reduce(&:total_usage)
    

    【讨论】:

      猜你喜欢
      • 2011-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多