7

Ho un'app che utilizza la gemma Ransack e la sto convertendo da Mysql a Postgres.Ransack, Postgres - ordina sulla colonna dalla tabella associata con distinto: true

In un caso in cui la colonna di ordinamento viene da una tabella associata e l'opzione distinto è impostata su true, Postgres getta questo errore:

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

La pagina github Ransack dice che, in un caso come questo, "sei da solo."

Qual è il migliore - qualsiasi! - strategia per gestire questo 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 

Grazie!

risposta

3

Ho appena affrontato lo stesso problema e una soluzione rapida e sporca che funziona per l'ordinamento a colonna singola aggiungerebbe un inizializzatore come segue. Questa patch per scimmie aggiunge la colonna di ordinamento mancante all'istruzione 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 
+0

Se aggiungo questa correzione, ottengo "NoMethodError - metodo non definito' paginate 'per # "quando provo a impaginare i risultati ... – Danny

+0

Se sostituisco relation.distinct con relation.uniq, tutto sembra funzionare bene ... (Rails 3.2) – Danny

+1

Urrà! Grazie. –

4

C'è un modo più semplice per risolvere questo problema. Utilizzare un'ActiveRecord unisce query o query di selezione per aggiungere le colonne necessarie, ad esempio:

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

In alternativa, se desideri solo selezionare alcune colonne, si potrebbe fare:

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

ho fatto un pull request per aggiornare il readme di Ransack.

+0

Grazie. Cosa succede se oltre a ordinare su questo, sto anche cercando su contact_type, usando una proprietà diversa. Ottengo il seguente errore. manca la clausola FROM per la tabella. Come potrei fare per risolverlo? – ShivamD

Problemi correlati