在Rails中干燥视图(number_to_currency)
-
05-07-2019 - |
题
我的代码类似于:
number_to_currency(line_item.price,:unit =>"£")
在各种模特中乱丢我的观点。由于我的应用程序仅处理GBP(£),我是否应该将其移动到我的每个模型中,以便 line_item.price
返回应该的字符串(即 number_to_currency( line_item.price,:unit =>"£")
和 line_item.price
是一样的。我想这样做我应该:
def price
number_to_currency(self.price, :unit => "£")
end
但这不起作用。如果模型中已经定义了 price
,那么当我将 def price
更改为 def amount
时,Rails会报告“堆栈级别太深”,然后它抱怨 number_to_currency
没有定义?
解决方案
number_to_currency是一个视图助手,因此在模型中不可用。
您可以通过在application_helper.rb中定义自己的帮助程序来保存一些关键笔划(因此它可供所有视图使用)。例如
def quid(price)
number_to_currency(price, :unit => "£")
end
然后在视图中调用它:
quid(line_item.price)
其他提示
如果要更改整个应用程序的默认值,可以编辑config / locales / en.yml
我的样子如下:# 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
除了单位之外的所有东西都是可选的,并且会回归到默认值,但我把它放进去,所以我知道我可以改变什么值。你也可以使用£标志而不是& pound;。
堆栈级别太深错误的原因是当您在 price
方法中说 self.price
时,您创建的是无限的递归调用price方法,因为您现在已经覆盖了普通的访问器方法。为避免这种情况,您需要使用属性哈希来访问price字段的值。例如类似的东西:
def price
number_to_currency(attributes['price'], :unit => "£")
end
除了 number_to_currency
在模型代码中不可用的事实,因为Larry K描述的原因。
这是我解决这个问题的方法..
# /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
在您的模型中,您可以执行此操作(并且您不会使用您不会使用的方法污染模型)
class Album < ActiveRecord::Base
include AppName::CurrencyHelper
def price
currency_to_number(amount)
end
end
然后,所有要更新的视图都包括您的某个app helper中的模块
module ApplicationHelper
# change default currency formatting to pounds..
include AppName::CurrencyHelper
end
现在,无论你在哪里使用数字到货币助手,它都会用英镑符号格式化,但你也拥有原始rails方法的所有灵活性,所以你可以像以前一样传递选项..
number_to_currency(amount, :unit => '
会将其转换回美元符号。
)
会将其转换回美元符号。
关于制作另一个辅助方法quid(price)以简化重复的另一个答案可能是最好的方法..但是..如果你真的想要访问模型中的视图助手,你可以做类似的事情:
# /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
然后您应该能够在模型类中执行此操作:
def price
helper = YourNamespace::Helper.instance
helper.number_to_currency(read_attribute('price'), :unit => "£")
end
从Rails 3开始
正如Larry K所描述的那样:
def quid(price)
number_to_currency(price, :unit => "£")
end