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.
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
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. –
'before_save: recalculate_fields' –