Vistas de secagem em trilhos (número_to_currency)
-
05-07-2019 - |
Pergunta
Eu tenho código semelhante a:
number_to_currency(line_item.price, :unit => "£")
espalhando minhas opiniões em vários modelos. Como meu aplicativo lida apenas no GBP (£), não devo mover isso para cada um dos meus modelos para que line_item.price
Retorna a string como deveria ser (ou seja, number_to_currency(line_item.price, :unit => "£")
e line_item.price
são os mesmos. Estou pensando que fazer isso, eu deveria:
def price
number_to_currency(self.price, :unit => "£")
end
Mas isso não funciona. Se price
já está definido no modelo, depois o Rails relata o 'nível da pilha muito profundo', quando eu mudar def price
para def amount
, então reclama que number_to_currency
não está definido?
Solução
número_to_currency é um auxiliar de exibição, portanto não está disponível nos modelos.
Você pode economizar alguns traços importantes definindo seu próprio ajudante em appold_helper.rb (para que esteja disponível para todas as visualizações). Por exemplo
def quid(price)
number_to_currency(price, :unit => "£")
end
Em seguida, chame de visualizações:
quid(line_item.price)
Outras dicas
Se você deseja alterar o padrão para todo o aplicativo, você pode editar o Config/Locales/en.yml
O meu se parece com o seguinte:
# 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: "£"
# These three are to override number.format and are optional
separator: "."
delimiter: ","
precision: 2
Tudo, exceto que a unidade, é opcional e voltará ao padrão, mas eu a coloquei para saber quais valores posso mudar. Você também pode usar o sinal de £ em vez de £.
A razão para o Nível de pilha muito profundo erro é que quando você diz self.price
no price
Método Você está criando uma chamada recursiva infinita para o seu método de preço, pois agora substituiu o método de acessador normal. Para evitar isso, você precisaria acessar o valor do campo de preços usando o hash dos atributos. por exemplo, algo como:
def price
number_to_currency(attributes['price'], :unit => "£")
end
exceto pelo fato de que number_to_currency
não está disponível no código do modelo pelo motivo que Larry K descreve.
Aqui estava minha abordagem a esse 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
Nos seus modelos, você pode fazer isso (e não estará poluindo seu modelo com métodos que não vai usar)
class Album < ActiveRecord::Base
include AppName::CurrencyHelper
def price
currency_to_number(amount)
end
end
Então, para que suas opiniões sejam atualizadas, inclua o módulo em um de seus ajudantes de aplicativos
module ApplicationHelper
# change default currency formatting to pounds..
include AppName::CurrencyHelper
end
Agora, em todos os lugares, você usa o número do ajudante de moeda, ele será formatado com um símbolo de libra, mas você também tem toda a flexibilidade do método do Rails original para poder passar as opções como antes ..
number_to_currency(amount, :unit => '$')
Voltará a um símbolo de dólar.
A outra resposta sobre fazer outro método auxiliar quid (preço) para simplificar a repetição é provavelmente a melhor abordagem ... no entanto ... se você realmente deseja acessar os ajudantes do modelo, poderá fazer algo como:
# /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
Então você poderá fazer isso na classe modelo:
def price
helper = YourNamespace::Helper.instance
helper.number_to_currency(read_attribute('price'), :unit => "£")
end
A partir de trilhos 3
Como Larry K descreve, mas com esta edição:
def quid(price)
number_to_currency(price, :unit => "£")
end