Secado de vistas en Rails (number_to_currency)
-
05-07-2019 - |
Pregunta
Tengo un código similar a:
number_to_currency (line_item.price,: unit = > " £ ")
ensuciando mis puntos de vista en varios modelos. Como mi solicitud solo se negocia en GBP (£), no debería mover esto a cada uno de mis modelos para que line_item.price
devuelva la cadena como debería ser (es decir, number_to_currency (line_item.price ,: unit = > " £ ")
y line_item.price
son iguales. Estoy pensando que para hacer esto debo:
def price
number_to_currency(self.price, :unit => "£")
end
pero esto no funciona. Si price
ya está definido en el modelo, Rails informa "nivel de pila demasiado profundo", cuando cambio def price
a def importe
, entonces se queja de que number_to_currency
no está definido?
Solución
number_to_currency es una vista auxiliar, por lo que no está disponible en modelos.
Puede guardar algunas pulsaciones de teclas definiendo su propio ayudante en application_helper.rb (para que esté disponible para todas las vistas). Por ejemplo,
def quid(price)
number_to_currency(price, :unit => "£")
end
Entonces llámalo en vistas:
quid(line_item.price)
Otros consejos
Si desea cambiar el valor predeterminado de toda su aplicación, puede editar config / locales / en.yml
El mío se ve así:
# 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
Todo, excepto la unidad, es opcional y volverá al valor predeterminado, pero lo puse para saber qué valores puedo cambiar. también puede usar el signo £ en lugar de & amp; pound ;.
El motivo del error nivel de pila demasiado profundo es que cuando dice self.price
en el método price
, está creando un infinito. llamada recursiva a su método de precio ya que ahora ha anulado el método de acceso normal. Para evitar esto, necesitaría acceder al valor del campo de precio utilizando los atributos hash. p.ej. algo como:
def price
number_to_currency(attributes['price'], :unit => "£")
end
excepto por el hecho de que number_to_currency
no está disponible en el código del modelo por la razón que describe Larry K.
Aquí estaba mi enfoque para este 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
en sus modelos puede hacer esto (y no contaminará su modelo con métodos que no va a utilizar)
class Album < ActiveRecord::Base
include AppName::CurrencyHelper
def price
currency_to_number(amount)
end
end
luego, para que sus vistas se actualicen, incluya el módulo en uno de sus ayudantes de aplicaciones
module ApplicationHelper
# change default currency formatting to pounds..
include AppName::CurrencyHelper
end
Ahora, en todos los lugares donde use el número para cambiar moneda, se formateará con un símbolo de libra, pero también tiene toda la flexibilidad del método de rieles original para que pueda pasar las opciones como lo hizo antes ...
number_to_currency(amount, :unit => '
lo convertirá de nuevo en un símbolo de dólar.
)
lo convertirá de nuevo en un símbolo de dólar.
La otra respuesta con respecto a hacer otro método auxiliar quid (precio) para simplificar la repetición es probablemente el mejor enfoque ... sin embargo ... si REALMENTE desea acceder a los asistentes de vista en el modelo, puede hacer 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
entonces deberías poder hacer esto en la clase de modelo:
def price
helper = YourNamespace::Helper.instance
helper.number_to_currency(read_attribute('price'), :unit => "£")
end
A partir de Rails 3
Como Larry K describe pero con esta edición:
def quid(price)
number_to_currency(price, :unit => "£")
end