2009-09-09 3 views
9

Ho codice simile a:essiccazione Vista in Rails (number_to_currency)

number_to_currency(line_item.price, :unit => "£")

sporcare le mie opinioni in vari modelli. Poiché la mia domanda riguarda solo GBP (£), non dovrei spostare questo in ciascuno dei miei modelli in modo che lo line_item.price restituisca la stringa come dovrebbe (cioè number_to_currency(line_item.price, :unit => "£") e line_item.price sono gli stessi. Sto pensando che per fare questo dovrei :.

def price 
number_to_currency(self.price, :unit => "£") 
end 

ma questo non funziona Se price è già definito nel modello, quindi Rails 'livello di stack troppo in profondità' i rapporti, quando cambio def price-def amount, poi si lamenta che number_to_currency non è definito?

+1

non è più SECCO, se si può solo impostare l'unità di default per GBP e utilizzare number_to_currency direttamente? –

risposta

12

number_to_currency è un helper di vista, quindi non è disponibile nei modelli

È possibile salvare alcuni tratti chiave definendo il proprio helper in application_helper.rb (quindi è disponibile per tutte le viste). Ad esempio

def quid(price) 
    number_to_currency(price, :unit => "£") 
end 

Poi lo chiamano in vista:

quid(line_item.price) 
6

Il motivo per il livello risma troppo in profondità errore è che quando si dice self.price nel metodo price si sta creando una chiamata ricorsiva infinita il metodo del prezzo come ora avete sostituito il normale metodo accessor. Per evitare ciò, è necessario accedere al valore del campo del prezzo utilizzando l'hash degli attributi. per esempio. qualcosa di simile:

def price 
number_to_currency(attributes['price'], :unit => "£") 
end 

tranne per il fatto che number_to_currency non è disponibile nel codice modello per la ragione Larry K descrive.

+0

Grazie per avermi spiegato la chiamata ricorsiva. – Gav

1

L'altra risposta per quanto riguarda fare un altro metodo di supporto quid (prezzo) per semplificare la ripetizione è probabilmente l'approccio migliore .. comunque .. se davvero desidera accedere vista aiutanti nel modello si può fare qualcosa di simile:

# /RAILS_ROOT/lib/your_namespace/helper.rb 
# 
# Need to access helpers in the model? 
# YourNamespace::Helper.instance.helper_method_name 
module YourNamespace 
    class Helper 
    include Singleton 
    include ActionView::Helpers 
    end 
end 

allora si dovrebbe essere in grado di farlo nella classe del modello:

def price 
    helper = YourNamespace::Helper.instance 
    helper.number_to_currency(read_attribute('price'), :unit => "£") 
end 
2

Qui era il mio approccio a questo problema ..

# /RAILS_ROOT/lib/app_name/currency_helper.rb 
module AppName 
    module CurrencyHelper  

    include ActionView::Helpers::NumberHelper 

    def number_to_currency_with_pound(amount, options = {}) 
     options.reverse_merge!({ :unit => '£' }) 
     number_to_currency_without_pound(amount, options) 
    end 

    alias_method_chain :number_to_currency, :pound 

    end 
end 

nei modelli si può fare questo (e non sarà inquinare il modello con metodi che non si intende utilizzare)

class Album < ActiveRecord::Base 
    include AppName::CurrencyHelper 

    def price 
    currency_to_number(amount) 
    end 
end 

poi per le vostre opinioni a tutti essere aggiornato includere il modulo in uno dei vostri aiutanti app

module ApplicationHelper 
    # change default currency formatting to pounds.. 
    include AppName::CurrencyHelper 
end 

Ora ovunque si utilizza il numero di aiutante di valuta verrà formattato con un simbolo della libbra, ma è anche tutto il flexiblity del metodo rotaie originale in modo da poter passare le opzioni come si fatto prima

number_to_currency(amount, :unit => '$') 

convertirà nuovamente in un simbolo del dollaro.

41

Se si desidera modificare il valore predefinito per tutta l'applicazione, è possibile modificare config/locali/en.yml

miniera di simile a questa:

# Sample localization file for English. Add more files in this directory for other locales. 
# See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. 
"en": 
    number: 
    currency: 
     format: 
      format: "%u%n" 
      unit: "&pound;" 
      # These three are to override number.format and are optional 
      separator: "." 
      delimiter: "," 
      precision: 2 

Tutto tranne l'unità è opzionale e tornare al valore predefinito, ma l'ho inserito in modo da sapere quali valori posso modificare. potresti anche utilizzare il simbolo £ anziché & sterlina ;.

+0

Grazie per il suggerimento; la documentazione dell'API di Rails per 'ActionView :: Helpers :: NumberHelper number_to_currency()' fornisce un esempio in cui l'impostazione ': locale =>" fr "' cambia il separatore e il delimitatore e la posizione del simbolo di valuta. Questo non funzionava per me, ma aggiungendo un 'config/locales/fr.yml' con impostazioni come sopra, ha iniziato a funzionare. – bjnord

+2

Avevo sempre usato un helper personalizzato, simile a come descrive la risposta accettata da Larry K, ma questo è molto più pulito. –

1

Come di Rails 3

As Larry K descrive ma con questa modifica:

def quid(price) 
    number_to_currency(price, :unit => "&pound;") 
end