보기보다는 모델에서 "number_to_currency"도우미 메서드를 사용하는 방법은 무엇입니까?
to_dollar
내 모델에서 다음과 같은 방법 을 사용 하고 싶습니다.
module JobsHelper
def to_dollar(amount)
if amount < 0
number_to_currency(amount.abs, :precision => 0, :format => "-%u%n")
else
number_to_currency(amount, :precision => 0)
end
end
end
class Job < ActiveRecord::Base
include JobsHelper
def details
return "Only " + to_dollar(part_amount_received) +
" out of " + to_dollar(price) + " received."
end
end
불행히도이 number_to_currency
방법은 여기서 인식되지 않습니다.
# <Job : 0x311eb00>에 대한 정의되지 않은 메소드`number_to_currency '
작동하는 방법에 대한 아이디어가 있습니까?
모델에서의 사용이 (일반적으로) MVC를 위반하기 때문에 사용할 수 없습니다 (귀하의 경우에는 그렇게 보입니다). 데이터를 가져 와서 프레젠테이션을 위해 조작하고 있습니다. 이것은 정의상 모델이 아니라 뷰에 속합니다.
다음은 몇 가지 해결책입니다.
발표자 또는보기 모델 개체를 사용하여 모델과보기를 중재합니다. 이것은 거의 확실히 다른 솔루션보다 더 많은 초기 작업이 필요하지만 거의 항상 더 나은 디자인입니다. 프레젠터 / 뷰 모델에서 헬퍼를 사용하는 것은 뷰 레이어에 상주하기 때문에 MVC를 위반하지 않으며, 전통적인 커스텀 Rails 헬퍼와 로직으로 채워진 뷰를 대체합니다.
Rails에 의존하는 대신 명시 적
include ActionView::Helpers::NumberHelper
으로JobsHelper
마법처럼로드했습니다. 모델에서 도우미에 액세스하면 안되므로 여전히 좋지 않습니다.MVC 및 SRP를 위반합니다 . 이를 수행하는 방법 은 fguillen의 답변 을 참조하십시오 . 나는 그것에 동의하지 않기 때문에 여기에서 그것을 반향하지 않을 것입니다. 그럼에도 불구하고 Sam의 답변 에서와 같이 프레젠테이션 방법으로 모델을 오염시키는 데 동의하지 않습니다 .
"하지만 내 모델에 내 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 패턴을 깨는 될 수 있지만 패턴을 깰 이유는 내가이 필요한 내 경우에는, 항상 있다는 것을 여러분 모두 동의 방법 포맷터 통화를 하는 템플릿 필터에서 사용 ( 액체 내 경우).
결국 나는 다음 과 같은 것을 사용하여 이러한 통화 포맷터 메서드에 액세스 할 수 있음을 알았습니다 .
ActionController::Base.helpers.number_to_currency
이 스레드가 매우 오래되었다는 것을 알고 있지만 누군가가 Rails 4+에서이 문제에 대한 해결책을 찾을 수 있습니다. 개발자는 다음을 사용하여 뷰 관련 모듈 / 클래스에 액세스하지 않고도 사용할 수있는 ActiveSupport :: NumberHelper를 추가했습니다.
ActiveSupport::NumberHelper.number_to_currency(amount, precision: 0)
You need to also include the 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
Piggybacking off of @fguillen
's response, I wanted to override the number_to_currency
method in my ApplicationHelper
module so that if the value was 0
or blank
that it would output a dash instead.
Here's my code in case you guys would find something like this useful:
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
You can use view_context.number_to_currency
directly from you controller or model.
@fguillen's way is good, though here's a slightly cleaner approach, particular given that the question makes two references to to_dollar
. I'll first demonstrate using Ryan Bates' code (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
Notice the call helpers.pluralize
. This is possible due to the method definition (def helpers
), which simply returns ActionController::Base.helpers
. Therefore helpers.pluralize
is short for ActionController::Base.helpers.pluralize
. Now you can use helpers.pluralize
multiple times, without repeating the long module paths.
So I suppose the answer to this particular question could be:
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
It is not a good practice but it works for me!
to import include ActionView::Helpers::NumberHelper in the controller. For example:
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
Hope it helps you!
Really surprised not one person has talked about using a Decorator. Their purpose is to solve the issue you are facing, and more.
https://github.com/drapergem/draper
EDIT: Looks like the accepted answer basically did suggest doing something like this. But yeah, you want to use decorators. Here's a great tutorial series to help you understand more:
https://gorails.com/episodes/decorators-from-scratch?autoplay=1
P.S. - @excid3 I accept free membership months LOL
You can just include ActiveSupport::NumberHelper
module, if you don't need additional features defined by ActionView
.
Helper methods are generally used for View files. It is not a good practice to use these methods in Model class. But if you want to use then Sam's answer is ok. OR I suggest you can write your own custom method.
'programing' 카테고리의 다른 글
Scala 목록에서 발생 횟수를 어떻게 계산할 수 있습니까? (0) | 2020.09.06 |
---|---|
Razor를 사용하여 DateTime 형식 변환 (0) | 2020.09.06 |
Ruby : 변수를 문자열로 병합 (0) | 2020.09.06 |
최대 값을 초과하지 않고 어떻게 변수를 증가시킬 수 있습니까? (0) | 2020.09.06 |
UIWebView에서 스크롤을 허용하지 않습니까? (0) | 2020.09.06 |