【问题标题】:DRYing Views in Rails (number_to_currency)在 Rails 中干燥视图 (number_to_currency)
【发布时间】:2010-11-26 21:09:35
【问题描述】:

我的代码类似于:

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

在各种模型中乱扔我的观点。由于我的应用程序仅以英镑 (£) 交易,我是否应该将其移至我的每个模型中,以便 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没有定义?

【问题讨论】:

  • 如果您可以将默认单位设置为 GBP 并直接使用 number_to_currency 不是更干吗?

标签: ruby-on-rails views dry


【解决方案1】:

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

除了单位之外的所有东西都是可选的,并且会回退到默认值,但我把它放进去,所以我知道我可以改变什么值。您也可以使用 £ 符号代替 £。

【讨论】:

  • 感谢您的提示; ActionView::Helpers::NumberHelper number_to_currency() 的 Rails API 文档提供了一个示例,其中设置 :locale => "fr" 会更改分隔符和定界符以及货币符号的位置。这对我不起作用,但通过添加具有上述设置的config/locales/fr.yml,它开始工作。
  • 我一直使用自定义助手,类似于 Larry K 接受的答案所描述的,但这更简洁。
【解决方案2】:

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

您可以通过在 application_helper.rb 中定义自己的助手来节省一些击键(因此它可用于所有视图)。例如

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

然后在视图中调用它:

quid(line_item.price)

【讨论】:

    【解决方案3】:

    stack level too deep 错误的原因是,当您在 price 方法中说 self.price 时,您正在创建对您的 price 方法的无限递归调用,因为您现在已经覆盖了普通访问器方法。为避免这种情况,您需要使用属性哈希访问价格字段的值。例如类似:

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

    除了 number_to_currency 由于 Larry K 所描述的原因在模型代码中不可用这一事实。

    【讨论】:

    • 感谢您向我解释递归调用位。
    【解决方案4】:

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

    # /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
    

    然后,为了让您的视图全部更新,请将该模块包含在您的应用助手之一中

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

    现在,无论您在哪里使用数字货币助手,它都会被格式化为英镑符号,但您还拥有原始 rails 方法的所有灵活性,因此您可以像以前一样传递选项..

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

    会将其转换回美元符号。

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

        从 Rails 3 开始

        正如 Larry K 所描述的,但有此编辑:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-05-07
          • 1970-01-01
          相关资源
          最近更新 更多