在Rails中干燥视图(number_to_currency)

时间:2009-09-09 15:00:10

标签: ruby-on-rails views dry

我的代码类似于:

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未定义?

6 个答案:

答案 0 :(得分:41)

如果要更改整个应用程序的默认值,可以编辑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;。

答案 1 :(得分:13)

number_to_currency是一个视图助手,因此在模型中不可用。

您可以通过在application_helper.rb中定义自己的帮助程序来保存一些关键笔划(因此它可供所有视图使用)。例如

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

然后在视图中调用它:

quid(line_item.price)

答案 2 :(得分:6)

堆栈级别太深错误的原因是,当您在self.price方法中说price时,您正在为您的价格方法创建无限递归调用现在已经覆盖了正常的访问器方法。为避免这种情况,您需要使用属性哈希来访问price字段的值。例如类似的东西:

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

除了由于Larry K描述的原因而在模型代码中没有number_to_currency这一事实。

答案 3 :(得分:2)

这是我解决这个问题的方法..

# /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 => '$')

会将其转换回美元符号。

答案 4 :(得分:1)

关于制作另一个辅助方法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

答案 5 :(得分:1)

从Rails 3开始

正如Larry K所描述的那样:

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