2013-07-04 3 views
20

Io corro Rails 4.di accesso specifiche per ogni modello costanti in una vista Rails

Ho un modello chiamato Challenge, e nel mio database sto memorizzare il status di ogni sfida in termini di 0-4.

Ma 0-4 non è molto semantica così voglio definire alcune variabili (Sto assumendo a costanti) in modo che in qualsiasi controller o visualizzare posso accedere al numero chiamando il costante:

# Challenge.rb 
class Challenge < ActiveRecord::Base 
    SUGGESTED = 0 
    APPROVED = 1 
    OPEN = 2 
    VOTING = 3 
    CLOSED = 4 
end 

voglio accedere a questi a mio avviso:

# challenge/_details.html.erb 
<% if @challenge.status == CLOSED %> 
    Challenge is closed, broheim! 
<% end %> 

Ma la mia vista non vuole rendere.

uninitialized constant ActionView::CompiledTemplates::CLOSED 

Qual è il modo migliore per impostare le variabili di stato in modo che possano essere accessibili ovunque ne ho bisogno? (Vale a dire, ovunque la variabile @challenge presente)

+2

vi consiglio di utilizzare un hash come una costante in questo caso. Perché? Perché ridurrà il numero di costanti differenti del tuo modello. Qualcosa come: 'STATUS = {suggerito: 0, approvato: 1, aperto: 2, ecc: ..}' e accedervi come 'Sfida :: STATUSES.approved' – MrYoshiji

risposta

41

Si dovrebbe accedere come segue:

Challenge::CLOSED 

Dal momento che il costante CLOSED è definita all'interno di una classe, è necessario accedere alla costante utilizzando l'operatore di risoluzione dell'ambito. Così, se il panorama che ci si controlla le cose come:

# challenge/_details.html.erb 
<% if @challenge.status == Challenge::CLOSED %> 
    Challenge is closed, broheim! 
<% end %> 
+1

Questo è un po 'ridondante considerando che la mia istruzione if fa già riferimento la variabile @challenge. C'è un modo per farlo così semantico che si legge come inglese? – alt

+0

Ehi grazie è molto utile per me. –

9

E 'una pessima idea di codificare questo tipo di affermazioni: l'oggetto deve gestire il proprio logica. Immagina se un giorno decidessi di unire lo stato, cambieresti ogni condizionale nella tua base di codice? No, dovresti usare un metodo che gestisce la logica.

farei quanto segue:

class Challenge < ActiveRecord::Base 
    SUGGESTED = 0 
    APPROVED = 1 
    OPEN = 2 
    VOTING = 3 
    CLOSED = 4 

    #defines: 
    # - suggested? 
    # - approved? 
    # - ... 
    %w(suggested approved open voting closed).each do |state| 
    define_method "#{state}?" do 
     status == self.class.const_get(state.upcase) 
    end 
    end 

    #if you prefer clarity, define each method: 

    def suggested? 
    status == SUGGESTED 
    end 

    #etc... 
end 

Quindi secondo lei:

<% if @challenge.closed? %> 
+0

Non sembra molto semantico. È anche una quantità piuttosto confusa di codice da avere nel modello di un progetto open source. Forse potresti approfondire il motivo per cui l'idea di MrYoshiji è così pessima? – alt

+2

Non è un grosso problema creare metodi se hanno senso, molto meglio che mettere la logica interna al di fuori del modello. @MrYoshiji l'idea va bene comunque. – apneadiving

+0

btw, come potrebbe essere più semantico di '@ challenge.closed?'? – apneadiving