Ransack, Postgres - sort on column from associated table with distinct: true

浪子不回头ぞ 提交于 2019-12-05 23:17:44

问题


I have an app that uses the Ransack gem and I'm converting it from Mysql to Postgres.

In an instance where the sort column is from an associated table and the distinct option is set to true, Postgres throws this error:

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

The Ransack github page says that, in a case like this, "you're on your own."

What's the best - any! - strategy for handling this scenario?

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

Thanks!


回答1:


There is a simpler way to solve this problem. Use an ActiveRecord joins query or select query to add the columns needed, for example:

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

Alternatively, if you only want to select a few columns, you could do:

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

I've done a pull request to update Ransack's readme.




回答2:


I've just faced with the same problem and a quick and dirty fix which works for single column sorting would be adding an initializer as follows. This monkey patch adds the missing sorting column into select statement.

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


来源:https://stackoverflow.com/questions/19748959/ransack-postgres-sort-on-column-from-associated-table-with-distinct-true

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!