2012-03-22 17 views
10

Domanda noob per Ruby on Rails: ecco un esempio della mia situazione: se ho il modello circle e l'attributo radius, dove devo eseguire i calcoli per circumference? Sarebbe nel modello o nel controller e come potrebbe apparire? circumference dovrebbe essere accessibile nel mio views.Rails - Dove devo calcolare gli attributi derivati?

Inoltre, dovrei essere corretto nel pensare che non è necessario rendere circumference un attributo che fa parte del mio modello/database poiché può essere derivato da un input utente radius?

risposta

14

La logica per il calcolo di un attributo derivato appartiene assolutamente al modello. La circonferenza è una proprietà del cerchio stesso, non una preoccupazione di come la stai presentando nell'interfaccia web.

Per accedere alla circonferenza da qualsiasi luogo, basta definire un metodo della classe, come la seguente:

require 'mathn' 
class Circle < ActiveRecord::Base 
    # assume `radius` column exists in the database 

    def circumference 
    Math::PI * 2 * radius 
    end 
end 

Dal momento che è computazionalmente piuttosto a buon mercato per calcolare la circonferenza, si può solo calcolare in base alle esigenze . Se si trattasse di qualcosa che ha coinvolto calcolo più complesso che non volevi eseguire più volte, si potrebbe Memoize come segue:

def circumference 
    @circumference ||= Math::PI * 2 * radius 
end 

che avrebbe stabilito la variabile @circumference esempio, la prima volta che il metodo viene chiamato, quindi restituisce il risultato del primo calcolo ad ogni chiamata successiva. Se lo facessi, dovresti assicurarti di impostare @circumference su nil quando il raggio è cambiato per assicurarti che sia accurato.

+0

Tornando al punto, dovrei chiarire con la mia seconda ipotesi - ho pensato che avrei dovuto fare i miei calcoli in 'app/models/circle.rb', ma sarei stato in grado di usare' circumference' come un semplice variabile (es .: variabile istanza '@ circumference') o dovrei aggiungerla come elemento della mia tabella di database per' circle'? – Nick

+1

Se aggiungete questo 'attr' alla vostra tabella allora avete bisogno di un codice addizionale per garantire che le modifiche al' raggio ', poi, attivino il ricalcolo della vostra "circonferenza". Ciò richiede che il 'def' dell'attributo sia gestito in modo leggermente diverso rispetto a questa risposta. –

+0

'before_save: recalculate_fields' –

Problemi correlati