programing

보기보다는 모델에서 "number_to_currency"도우미 메서드를 사용하는 방법은 무엇입니까?

nasanasas 2020. 9. 6. 10:07
반응형

보기보다는 모델에서 "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 "&ndash;"
    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.

https://github.com/rails/rails/blob/44260581bec06e4ce05f3dd838c8b4736fc7eb1d/actionview/lib/action_view/helpers/number_helper.rb#L383


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.

참고URL : https://stackoverflow.com/questions/5176718/how-to-use-the-number-to-currency-helper-method-in-the-model-rather-than-view

반응형