如何使用“number_to_currency"模型中的辅助方法而不是视图? [英] How to use the "number_to_currency" helper method in the model rather than view?
问题描述
我想在我的模型中使用 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屋!