Rails按关联question_articles表两列之和排序报disallow_raw_sql错误如何解决
这个错误是Rails 6.1及以上版本的安全校验机制触发的,框架默认禁止在order等查询方法中直接传入未标记的原始SQL字符串,用于防范SQL注入风险。
方案1:使用Arel构造查询(最推荐)
Arel是Rails内置的SQL抽象层,无需手写原始SQL,安全且兼容性强。
如果单个Question仅对应一条question_articles记录,写法如下:
question_article_table = QuestionArticle.arel_table Question .joins(:question_articles) # 如需预加载中间表避免N+1可保留 .includes(:question_articles) .order((question_article_table[:admin_usages_count] + question_article_table[:user_usages_count]).desc)
如果单个Question对应多条question_articles记录,需要先对关联的所有中间表字段求和再排序,写法如下:
question_article_table = QuestionArticle.arel_table sum_expression = question_article_table[:admin_usages_count] + question_article_table[:user_usages_count] Question .joins(:question_articles) .group(:id) .order(Arel::Nodes::Sum.new(sum_expression).desc)
方案2:标记安全SQL片段
如果你确认该SQL片段不存在用户输入拼接风险,可以用Arel.sql包裹原始SQL,告知框架该内容是安全的,跳过安全校验:
Question .joins(:question_articles) # 如需预加载中间表避免N+1可保留 .includes(:question_articles) .order(Arel.sql('question_articles.admin_usages_count + question_articles.user_usages_count DESC'))
补充说明:你原代码中的joins(:articles)属于冗余关联,你需要用到的排序字段都在question_articles中间表上,直接关联中间表即可减少不必要的表连接,提升查询效率。
内容的提问来源于stack exchange,提问作者spirito_libero
相关产品推荐
相关产品推荐

