7

我有一个使用 Ransack gem 的应用程序,我正在将它从 Mysql 转换为 Postgres。

在排序列来自关联表且 distinct 选项设置为 true 的情况下,Postgres 会抛出此错误:

PG::InvalidColumnReference: ERROR:  for SELECT DISTINCT, ORDER BY expressions must appear in select list

Ransack github 页面说,在这种情况下,“你只能靠你自己”。

什么是最好的 - 任何!- 处理这种情况的策略?

q = Contact.includes(:contact_type).search
q.sorts = ['contact_type_name asc']
q.result(distinct: true)
PG::InvalidColumnReference: ERROR:  for SELECT DISTINCT, ORDER BY expressions must appear in select list

谢谢!

4

2 回答 2

8

有一种更简单的方法可以解决这个问题。使用 ActiveRecord 连接查询或选择查询来添加所需的列,例如:

q = Contact.search
q.sorts = ['contact_type_name asc']
q.result(distinct: true).
  includes(:contact_type).
  joins(:contact_type)

或者,如果您只想选择几列,您可以这样做:

q = Contact.search
q.sorts = ['contact_type_name asc']
q.result(distinct: true).
  select('contacts.*, contact_type.name')

我已经完成了更新 Ransack 的自述文件的拉取请求。

于 2015-09-29T03:21:21.790 回答
3

我刚刚遇到了同样的问题,一个适用于单列排序的快速而肮脏的修复方法是添加一个初始化程序,如下所示。这个猴子补丁将缺少的排序列添加到 select 语句中。

module Ransack
  module Adapters
    module ActiveRecord
      class Context < ::Ransack::Context
        def evaluate(search, opts = {})
          viz = Visitor.new
          relation = @object.where(viz.accept(search.base))
          if search.sorts.any?
            _vaccept = viz.accept(search.sorts)
            table  = _vaccept.first.expr.relation.name
            column = _vaccept.first.expr.name
            relation = relation.except(:order).reorder(_vaccept).select("#{@default_table.name}.*, #{table}.#{column}")
          end
          opts[:distinct] ? relation.distinct : relation
        end
      end
    end
  end
end
于 2014-02-16T13:03:03.660 回答