2012-06-28 6 views
5

voglio inizializzare una variabile di istanza nel mio modello di Rails che conterrà un array e voglio accedere a questa variabile in altri metodi all'interno il mio modello. Ho provato questo:variabili di istanza in Rails Modello

class Participant < ActiveRecord::Base 

    @possible_statuses = [ 
    'exists', 
    'paired', 
    'quiz_finished', 
    'quiz_results_seen', 
    'money_sent' 
    ] 

    def statuses 
    @possible_statuses 
    end 

Ma quando ho provato quanto segue con console rotaie:

Participant.first.statuses 

Io torno a zero :(

Perché accade questo c'è un modo di realizzare? cosa sto cercando di realizzare?

risposta

3

La migliore risposta per me è stato quello di creare una variabile di classe, non una variabile di istanza:

@@possible_statuses = [ 
    'exists', 
    'paired', 
    'chat1_ready', 
    'chat1_complete' 
] 

Potrei allora liberamente accedervi in ​​metodi della classe:

def status=(new_status) 
    self.status_data = @@possible_statuses.index(new_status) 
    end 
+1

Se il valore di questa variabile di classe sarà costante, allora va bene altrimenti rimanda questo http://stackoverflow.com/questions/9396563/why-should- noi-evitiamo-con-class-variabili rotaie-in- – Bot

10

Si consiglia di utilizzare una costante per questo tipo di casi:

class Participant < ActiveRecord::Base 

    STATUSES = [ 
    'exists', 
    'paired', 
    'quiz_finished', 
    'quiz_results_seen', 
    'money_sent' 
    ] 

Se si desidera accedere quella matrice dalla classe dentro, basta fare STATUSES, e dall'uso classe al di fuori Participant::STATUSES

2

Nel tuo esempio, @possible_statuses è una variabile della classe piuttosto che su ogni istanza di l'oggetto. Ecco un esempio piuttosto verboso di come si potrebbe raggiungere questo obiettivo:

class Participant < ActiveRecord::Base 

    @possible_statuses = [ 
    'exists', 
    'paired', 
    'quiz_finished', 
    'quiz_results_seen', 
    'money_sent' 
    ] 

    def self.possible_statuses 
    @possible_statuses 
    end 

    def possible_statuses 
    self.class.possible_statuses 
    end 

    def statuses 
    possible_statuses 
    end 

end 

Come già detto in altre risposte, se questo elenco di stati non cambia mai, è necessario utilizzare una costante, piuttosto che una variabile.

+0

Ho 2 modelli : Lavoro e organizzazione. Un'organizzazione ha molti lavori e un lavoro appartiene a un'organizzazione. Le organizzazioni pubblicano lavori, devono essere approvati per essere visti ovunque nella mia app. Entrambi possono essere cercati (per essere mai trovati, devono essere approvati). Quello che voglio fare è avere una variabile nel mio modello di lavoro che è "lavori la cui organizzazione è stata approvata". In modo che quando scrivo il metodo di ricerca per i lavori, posso avere qualcosa come "@ approved_jobs.where ('titolo LIKE? E descrizione LIKE?', Params [: search], params [: search]). Dove e come vorresti definire la variabile @approved_jobs di cui ho bisogno? thx – Myna

+0

Vorrei usare il database per risolvere questo problema Aggiungere un campo booleano approvato alla tabella dei lavori, quindi aggiungere un ambito - "ambito: approvato, dove (: approvato => vero)". Quindi usi Job.approved invece di @approved_jobs. –

+0

La tabella dell'organizzazione ha un valore booleano approvato e non ho un booleano approvato per Lavori. Se creo anche un booleano per i lavori, come faccio a dire "se un'organizzazione è approvato, anche tutti i suoi lavori devono essere approvati. E viceversa "usando le associazioni e i modelli? – Myna

0

La variabile di istanza esisterà solo quando si crea il modello, dal momento che non viene memorizzato in un database da nessuna parte. Dovresti renderlo costante come suggerito da Nobita. In alternativa, si potrebbe rendere un modulo come ...

module Status 
    EXISTS = "exists" 
    PAIRED = "paired" 
    QUIZ_FINISHED = "quiz_finished" 
    QUIZ_RESULTS_SEEN = "quiz_results_seen" 
    MONEY_SENT = "money_sent" 

    def self.all 
    [EXISTS, PAIRED, QUIZ_FINISHED, QUIZ_RESULTS_SEEN, MONEY_SENT] 
    end 
end 

Questo ti dà un po 'più di controllo e flessibilità, IMO. Dovresti includere questo codice annidato nel tuo modello.