Он недоступен, потому что его использование в модели (обычно) нарушает MVC (и, похоже, в вашем случае). Вы берете данные и манипулируете ими для презентации. Это, по определению, принадлежит взгляду, а не модели.
Вот несколько решений:
Используйте объект модели презентатора или представления в качестве посредника между моделью и представлением. Это почти наверняка требует больше первоначальной работы, чем другие решения, но почти всегда лучше. Использование помощников в модели презентатора / представления не нарушает MVC, так как они находятся на уровне представления, заменяя традиционные пользовательские помощники Rails и представления с логикой.
Явно include ActionView::Helpers::NumberHelper
in JobsHelper
вместо того, чтобы зависеть от Rails, который волшебным образом загрузил его за вас. Это все еще не очень хорошо, так как вам не нужно обращаться к помощнику из модели.
Нарушают MVC и SRP . См . Ответ fguillen, чтобы узнать, как это сделать. Я не буду повторять это здесь, потому что я не согласен с этим. Тем не менее, я не согласен с загрязнением вашей модели методами представления, как в ответе Сэма .
Если вы думаете: «Но мне это действительно нужно, чтобы написать свои to_csv
& to_pdf
методы в моей модели!», То вся ваша предпосылка неверна - в конце концов, у вас нет to_html
метода, не так ли? И все же ваш объект очень часто отображается как HTML. Рассмотрите возможность создания нового класса для генерации вашего вывода вместо того, чтобы ваша модель данных знала, что такое CSV ( потому что он не должен ).
Что касается использования помощников для ошибок валидации ActiveModel в модели, что ж, извините, но ActiveModel / Rails нас всех обманули, заставив сообщения об ошибках реализовываться на уровне данных, вместо того, чтобы возвращать семантическую идею ошибки, которая должна быть понял позже - вздох . Вы можете обойти это, но в основном это означает, что ActiveModel :: Errors больше не используется. Я сделал это, работает хорошо.
В стороне, вот полезный способ включить помощников в модель презентатора / представления, не загрязняя ее набор методов (потому что способность делать, например, MyPresenterOrViewModel.new.link_to(...)
не имеет смысла):
class MyPresenterOrViewModel
def some_field
helper.number_to_currency(amount, :precision => 0)
end
private
def helper
@helper ||= Class.new do
include ActionView::Helpers::NumberHelper
end.new
end
end
Я согласен со всеми вами, что это может нарушить шаблон MVC, но всегда есть причины для нарушения шаблона, в моем случае мне понадобились эти методы форматирования валюты, чтобы использовать их в фильтре шаблона ( в моем случае Liquid ).
В конце концов я обнаружил, что могу получить доступ к этим методам форматирования валют, используя такие вещи:
источник
Я знаю, что эта ветка очень старая, но кто-то может поискать решение этой проблемы в Rails 4+. Разработчики добавили ActiveSupport :: NumberHelper, который можно использовать без доступа к модулям / классам, связанным с просмотром, используя:
ActiveSupport::NumberHelper.number_to_currency(amount, precision: 0)
источник
number_to_percentage
в консоли Rails. Благодарность!Вам также необходимо включить ActionView :: Helpers :: NumberHelper
class Job < ActiveRecord::Base include ActionView::Helpers::NumberHelper include JobsHelper def details return "Only " + to_dollar(part_amount_received) + " out of " + to_dollar(price) + " received." end end
источник
details
помощника.Воспользовавшись
@fguillen
ответом, я хотел переопределитьnumber_to_currency
метод в моемApplicationHelper
модуле, чтобы, если бы значение было0
илиblank
оно выводило вместо этого тире.Вот мой код на случай, если вы, ребята, найдете что-то вроде этого полезным:
module ApplicationHelper def number_to_currency(value) if value == 0 or value.blank? raw "–" else ActionController::Base.helpers.number_to_currency(value) end end end
источник
Вы можете использовать его
view_context.number_to_currency
прямо с вашего контроллера или модели.источник
Способ @fguillen хорош, хотя здесь есть немного более чистый подход, особенно учитывая, что в вопросе есть две ссылки на
to_dollar
. Сначала я продемонстрирую использование кода Райана Бейтса ( http://railscasts.com/episodes/132-helpers-outside-views ).def description "This category has #{helpers.pluralize(products.count, 'product')}." end def helpers ActionController::Base.helpers end
Обратите внимание на звонок
helpers.pluralize
. Это возможно благодаря определению метода (def helpers
), который просто возвращаетActionController::Base.helpers
. Следовательно,helpers.pluralize
это сокращение отActionController::Base.helpers.pluralize
. Теперь вы можете использоватьhelpers.pluralize
несколько раз, не повторяя длинные пути модуля.Итак, я полагаю, что ответ на этот конкретный вопрос может быть следующим:
class Job < ActiveRecord::Base include JobsHelper def details return "Only " + helpers.to_dollar(part_amount_received) + " out of " + helpers.to_dollar(price) + " received." end def helpers ActionView::Helpers::NumberHelper end end
источник
Это не очень хорошая практика, но у меня она работает!
для импорта включите ActionView :: Helpers :: NumberHelper в контроллер. Например:
class ProveedorController < ApplicationController include ActionView::Helpers::NumberHelper # layout 'example' # GET /proveedores/filtro # GET /proveedores/filtro.json def filtro @proveedores = Proveedor.all respond_to do |format| format.html # filtro.html.erb format.json { render json: @proveedores } end end def valuacion_cartera @total_valuacion = 0 facturas.each { |fac| @total_valuacion = @total_valuacion + fac.SumaDeImporte } @total = number_to_currency(@total_valuacion, :unit => "$ ") p '*'*80 p @total_valuacion end end
Надеюсь, это вам поможет!
источник
Действительно удивлен, что ни один человек не рассказал об использовании декоратора. Их цель - решить проблему, с которой вы столкнулись, и многое другое.
https://github.com/drapergem/draper
РЕДАКТИРОВАТЬ: Похоже, что принятый ответ в основном предлагал сделать что-то вроде этого. Но да, вы хотите использовать декораторы. Вот отличная серия руководств, которая поможет вам понять больше:
https://gorails.com/episodes/decorators-from-scratch?autoplay=1
PS - @ excid3 Я принимаю месяцы бесплатного членства LOL
источник
Вы можете просто
include ActiveSupport::NumberHelper
модуль, если вам не нужны дополнительные функции, определенныеActionView
.https://github.com/rails/rails/blob/44260581bec06e4ce05f3dd838c8b4736fc7eb1d/actionview/lib/action_view/helpers/number_helper.rb#L383
источник
Вспомогательные методы обычно используются для файлов просмотра. Не рекомендуется использовать эти методы в классе Model. Но если вы хотите использовать, то ответ Сэма в порядке. ИЛИ Я предлагаю вам написать свой собственный метод.
источник