2013-10-28 19 views
6

Come scrivere correttamente?Rails 4 Sintassi - Condizioni multiple

Request.pending.where(.....) ## Request.pending = request.state_id in (1..3) 

in cui queste sono le condizioni:

approver1_id = current_user and state_id = 1 
or 
approver2_id = current_user and state_id = 2 
or 
approver3_id = current_user and state_id = 3 

Sarebbe davvero bello se potessi mettere queste condizioni nel modello per l'uso in altri controller/vista, anche perché userò queste condizioni abbastanza spesso in tutta l'app.

+0

Forse 'Request.pending.where (approver1_id: current_user, state_id: 1)'. O hai bisogno di tutti e 3 in quel momento? – zishe

+0

Spiacente, ho dimenticato l'OR tra ... –

risposta

11

Prova:

Request.pending.where(
    '(approver1_id= ? AND state_id= ?) OR 
    (approver2_id= ? AND state_id= ?) OR 
    (approver3_id= ? AND state_id= ?)', 
    current_user.id, 
    1, 
    current_user.id, 
    2, 
    current_user.id, 
    3 
) 

Edit: ho dimenticato che si dovrebbe usare i due punti. E non dovrebbe essere "current_user.id"? Inoltre, non è chiaro se la tua richiesta utilizza i tre parametri approver1_id - approver3_id o solo un approvatore_id per richiesta.

Modifica 2: Query modificata a SQL.

+0

Hm, entrambe le risposte sopra ignorano la condizione current_user - mostra le richieste che incontrano state_ids 1-3, ma ignora l'approvatore1-3. L'ho provato con current_user e current_user.id. –

+0

A REQUEST ha tre approvatori per tre stati. Sto solo richiamando richieste in sospeso con l'ambito: 'Request.pending = state_id 1-3, che è: (In attesa di approvazione 1, in attesa di approvazione 2, in attesa di approvazione 3) .' Se la richiesta è in attesa di approvazione 1 e io sono l'approvatore 1, il record deve essere mostrato nella mia lista - lo stesso se sono Approver 2 e la richiesta è in attesa di approvazione 2 ... ecc. Ma, se sono Approver 1 e la richiesta è in attesa di approvazione 2, allora non voglio per vedere il disco nella mia lista. –

+0

@KatieM l'utente corrente può essere solo uno alla volta, giusto? Ecco perché sto controllando solo current_user.id. Forse provi a migliorare il tuo schema DB. Altrimenti rendi la tua domanda più specifica. –

1

Bene

In primo luogo ottenere tutte le vendite state_id & in array. e quindi passare quella matrice nella clausola where. È simile alla query Mysql IN.

Da qui la vostra richiesta sarà qualcosa di simile:

state_id = [1, 2, 3] 
Request.pending.where(:state_id => state_id AND :approved_id => current_user.id) 

Spero che vi accompagnerà il risultato desiderato.

+1

le barre 4 non accettano 'Request.pending.where ('state_id IN [1,2,3]')'? – Edmund

+0

Request.pending è già definito nel modello. Ho bisogno del numero di stato_id per abbinare il numero approver_id. –

7

Per rispondere alla seconda parte della tua domanda circa il riutilizzo di questa query, si può solo definire un metodo di classe su Request che accetta un parametro utente:

# usage: Request.pending_approval(current_user) 
def self.pending_approval(user) 
    pending.where("(approver1_id = :user AND state_id = 1) OR 
       (approver2_id = :user AND state_id = 2) OR 
       (approver3_id = :user AND state_id = 3)", 
       user: user) 
end 

Se si vuole essere in grado di riutilizzare i singoli frammenti della query e combinarli secondo le necessità, vedere this related answer (Nota, la risposta collegata a è migliore di quella accettata, IMO).