Вопрос

У меня есть код, похожий на:

number_to_currency (line_item.price,: unit = > " & # 163; ")

засорять мои взгляды в разных моделях. Поскольку мое приложение работает только в фунтах стерлингов (& # 163;), я не должен перемещать это в каждую из моих моделей, чтобы line_item.price возвращал строку в том виде, в каком она должна быть (т.е. number_to_currency ( line_item.price,: unit = > " & # 163; ") и line_item.price одинаковы. Я думаю, что для этого мне нужно:

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

но это не работает. Если цена уже определена в модели, то Rails сообщает о «слишком большом уровне стека», когда я изменяю def price на def amount , тогда он жалуется, что 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

Все, кроме единицы, является необязательным и будет иметь значение по умолчанию, но я вставил его, чтобы знать, какие значения я могу изменить. Вы также можете использовать & # 163; знак вместо & amp; фунт;.

Причина ошибки слишком большой уровень стека заключается в том, что когда вы говорите self.price в методе price , вы создаете бесконечное число рекурсивный вызов вашего метода цены, поскольку вы переопределили обычный метод доступа. Чтобы избежать этого, вам нужно получить доступ к значению поля цены, используя хэш атрибутов. например что-то вроде:

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

за исключением того факта, что number_to_currency недоступен в коде модели по причине, описанной Ларри К.

Вот мой подход к этой проблеме.

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

преобразует его обратно в символ доллара.

)

преобразует его обратно в символ доллара.

Другой ответ, касающийся создания другого вспомогательного метода 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

Как описывает Ларри К, но с этим редактированием:

def quid(price)
   number_to_currency(price, :unit => "&pound;")
 end
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top