2011-11-06 7 views
17

Ho un campo tipo in un modello chiamato utente che è un int nel db. Il valore delle specifiche int è il tipo di negozio che è. Esempio:Il miglior posto per memorizzare costanti specifiche del modello nei binari 3.1?

  • 0 = mamma
  • 1 = padre
  • 2 = nonna
  • e così via

Ho diversi altri campi come questo in modo è eccessivo per creare tabelle di associazione .

Invece di cercare quei valori int oltre il posto nelle istruzioni condizionali nella logica del modello e del controllore, c'è un posto nelle rotaie per memorizzare queste costanti.

In modo che potessi farlo dai miei modelli e controller?

if myuser.type == MOM 
elsif myuser.type == GRAND_MOTHER 

EDIT: Soluzione sono andato con alla fine:

Nel modello:

# constants 
    TYPES = { 
    :mom => 0, 
    :dad => 1, 
    :grandmother => 2, 
    :grandfather => 3 
    } 

Nella logica:

if u.type == User::TYPES[:mom] 

Anche se è più lungo, mi sono sentito è più intuitivo per gli altri sviluppatori quando leggono il mio codice. Grazie a Taro qui sotto per questa soluzione.

risposta

39

Qualcosa di simile:

class User < ActiveRecord::Base 

    TYPES = %w{ mom dad grandmother grandfather son } 

    TYPES.each_with_index do |meth, index| 
    define_method("#{meth}?") { type == index } 
    end 

end 


u = User.new 
u.type = 4 
u.mom? # => false 
u.son? # => true 
+0

Ottima soluzione. C'è un modo per usare i valori nel compito? Qualcosa come ... 'u.type = MOM' ... altrimenti nel caso in cui un valore modificato nel tempo richiederebbe modifiche a quel valore in più file. – Hopstream

+7

Inserisci la costante all'interno della classe e fai riferimento ad essa come 'Utente :: MOM'. – d11wtq

+0

È possibile utilizzare questa stessa notazione per accedere al metodo in un modello senza creare prima l'oggetto come in PHP? Ottengo un errore "metodo non definito" se faccio qualcosa come 'ModelName :: mydef()' – Hopstream

1

Un modo di essere per scrivere un file nella cartella inizializzatori o nella cartella lib

dicono app_contants.rb e in questo file è possibile scrivere

MOM=1 

DAD=2 
  1. In caso si scriva un inizializzatore yo u può fare

user.type == mamma

2. Se si crea un file lib ne fanno un modulo

module app_constants 
    mom = 1 
    dad = 2 
    end 

e semplicemente includere questo modulo, ovunque tu necessario

+0

poiché tutte le costanti che voglio sono relative ai campi nei modelli, sarebbe una buona pratica includere i rispettivi moduli nei loro modelli? Inoltre, queste costanti sarebbero disponibili in qualsiasi controller o file rake che utilizza tali modelli? – Hopstream

9

Dal Rails 4.1, non v'è il supporto per ActiveRecord::Enum.

C'è un tutorial utile here, ma in breve:

# models/user.rb 
class User < ActiveRecord::Base 
    enum family_role: [ :mum, :dad, :grandmother] 
end 

# logic elsewhere 
u = User.first 
u.family_role = 'mum' 
u.mum? # => true 
u.family_role # => 'mum' 

Nota: Per convertire dal vostro schema di corrente (in cui il database già memorizza i numeri corrispondenti ai valori), è necessario utilizzare la sintassi hash:

enum family_role: { mum: 0, dad: 1, grandmother: 2 } 

Vorrei inoltre proporre di riservare 0 per lo stato predefinito, ma questa è solo una convenzione e non critica.

+1

E sì, so che questo non aiuta la tua domanda specifica su Rails 3.1, ma spero che aiuti gli altri. –

+0

Bello. +1 per pensare ai futuri lettori – JGutierrezC

Problemi correlati