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)
답변
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
답변
@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
. 먼저 Ryan Bates의 코드 ( 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
