我有一个使用Ransack gem的应用程序,我将它从Mysql转换为Postgres。
在sort列来自关联表并且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
谢谢!
答案 0 :(得分:5)
有一种更简单的方法可以解决这个问题。使用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')
我已经完成了pull request来更新Ransack的自述文件。
答案 1 :(得分: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