5

ho questo definito Enum per i ruoli:ordine su ordinazione sulla base Enum valori

enum role: {ordinary: 0, manager: 1, admin: 2} 

avrei voluto ordinare una collezione di oggetti nel seguente ordine:

admin (first all admins) 
ordinary (then all ordinaries) 
manager (and lastly all managers) 

Questo è possibile a tutti ?

risposta

5

Una soluzione per questo:

class YourModel < ActiveRecord::Base 
    ROLE_ORDERS = [2, 0, 1] 

    scope :order_by_role, -> { 
    order_by = ['case'] 
    ROLE_ORDERS.each_with_index do |role, index| 
     order_by << "WHEN role=#{role} THEN #{index}" 
    end 
    order_by << 'end' 
    order(order_by.join(' ')) 
    } 
end 

Allora la vostra richiesta sarà semplice come questo:

YourModel.order_by_role 

La query generato è:

SELECT * from your_models 
ORDER BY (CASE 
      WHEN role=2 THEN 0 
      WHEN role=0 THEN 1 
      WHEN role=1 then 2 
      END 
     ) 

buon riferimento da this

+0

Hm, sto ottenendo questo errore (purtroppo troppo avanzato per me da analizzare): ActiveRecord :: StatementInvalid: PG :: SyntaxError: ERRORE: errore di sintassi alla fine dell'input LINEA 1: ... ASEN QUANDO ruolo = 2 THEN 0 WHEN role = 0 THEN 1 WHEN role = 1 THEN 2 ^ : SELECT " utenti ". * FROM" users "ORDER BY caso WHEN role = 2 THEN 0 WHEN role = 0 THEN 1 WHEN role = 1 THEN 2 –

+0

Ehi, ho dimenticato di aggiungere 'END' alla fine dell'istruzione' CASE', basta correggerla –

+0

Questo è abbastanza brillante. Sembra brutto, ma la soluzione migliore IMO per un problema altrimenti molto appiccicoso. –

0

Grazie a this answer sono arrivato fino a questo:

order("role = 0 DESC, role = 1 DESC, role = 2 DESC") 

Oppure, come un campo di applicazione con argomenti opzionali:

scope :order_by_roles, -> (first = :admin, second = :ordinary, third = :manager) { 
    order("role = #{User.roles[first]} DESC, role = #{User.roles[second]} DESC, role = #{User.roles[third]} DESC") 
}