如何使用“number_to_currency"模型中的辅助方法而不是视图? [英] How to use the "number_to_currency" helper method in the model rather than view?

查看:39
本文介绍了如何使用“number_to_currency"模型中的辅助方法而不是视图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的模型中使用 to_dollar 方法,如下所示:

I would like to use to_dollar method in my model like this:

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 方法在此处无法识别:

Unfortunately, the number_to_currency method is not recognized here:

未定义的方法 `number_to_currency' 用于 #<Job:0x311eb00>

undefined method `number_to_currency' for #<Job:0x311eb00>

任何想法如何使它工作?

Any ideas how to make it work?

推荐答案

它不可用,因为它在模型中的使用(通常)违反了 MVC(在您的情况下似乎确实如此).您正在获取数据并对其进行操作以进行演示.根据定义,这属于视图,而不属于模型.

It’s not available because its use in a model (typically) violates MVC (and it does seem to in your case). You're taking data and manipulating it for presentation. This, by definition, belongs in the view, not the model.

以下是一些解决方案:

  • 使用演示者或视图模型对象在模型和视图之间进行调解.这几乎肯定比其他解决方案需要更多的初始工作,但几乎总是更好的设计.在演示者/视图模型中使用助手不会违反 MVC,因为它们驻留在视图层中,取代了传统的自定义 Rails 助手和逻辑填充视图.

  • Use a presenter or view model object to mediate between the model and view. This almost definitely requires more initial work than other solutions, but is almost always a better design. Using helpers in a presenter/view-model doesn’t violate MVC, as they reside in the view layer, replacing traditional custom Rails helpers and logic-filled views.

JobsHelper 中显式地包含 ActionView::Helpers::NumberHelper 而不是依赖 Rails 为您神奇地加载它.这仍然不是很好,因为您不应该从模型访问帮助程序.

Explicitly include ActionView::Helpers::NumberHelper in JobsHelper instead of depending on Rails to have magically loaded it for you. This is still not great, as you shouldn’t access a helper from a model.

违反 MVC &SRP.请参阅fguillen 的回答,了解如何执行此操作.我不会在这里附和,因为我不同意.更重要的是,我是否不同意使用 Sam 的回答中的表示方法污染您的模型.

Violate MVC & SRP. See fguillen’s answer for how to do this. I won’t echo it here because I don’t agree with it. Even more so, though, do I disagree with polluting your model with presentation methods as in Sam’s answer.

如果您认为但我真的需要它来编写我的 to_csv &to_pdf 方法在我的模型中!",那么你的整个前提是错误的——毕竟,你没有 to_html 方法,是吗?然而你的对象经常被呈现为 HTML.考虑创建一个用于生成输出的新类,而不是让您的数据模型知道 CSV 是什么(因为它不应该t).

If you think "but I really need this to write my to_csv & to_pdf methods in my model!", then your entire premise is wrong—after all, you don’t have a to_html method, do you? And yet your object is very often rendered as HTML. Consider creating a new class for generating your output instead of making your data model know what a CSV is (because it shouldn’t).

至于在模型中使用帮助器来处理 ActiveModel 验证错误,好吧,我很抱歉,但是 ActiveModel/Rails 通过强制在数据层中实现错误消息而不是返回语义将我们搞砸了以后要意识到错误的想法——叹气.你可以解决这个问题,但这基本上意味着不再使用 ActiveModel::Errors.我已经做到了,效果很好.

As for using helpers for ActiveModel validation errors in the model, well, I’m sorry but ActiveModel/Rails has screwed us all there by forcing error messages to be realized in the data layer, rather than returning the semantic idea of an error to be realized later—sigh. You can get around this, but it basically means not using ActiveModel::Errors anymore. I’ve done it, it works well.

顺便说一句,这是一种在演示者/视图模型中包含助手而不污染其方法集的有用方法(因为能够执行例如 MyPresenterOrViewModel.new.link_to(...) 没有意义):

As an aside, here’s a useful way to include helpers in a presenter/view-model without polluting its set of methods (because being able to do e.g. MyPresenterOrViewModel.new.link_to(...) makes no sense):

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

这篇关于如何使用“number_to_currency"模型中的辅助方法而不是视图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆