我想在我的模型中使用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方法:

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

有什么办法让它工作吗?

推荐答案

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

以下是一些解决方案:

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

  • JobsHelper中显式加载include ActionView::Helpers::NumberHelper,而不是依靠Rails为您神奇地加载它.这仍然不太好,因为您不应该从模型中访问助手.

  • 违反MVC&;SRP.有关如何操作,请参见fguillen’s answer.我不会在这里重复,因为我不同意.然而,更重要的是,我不同意用Sam’s answer中的表示方法污染您的模型.

如果你认为"但我真的需要这个来在我的模型中编写我的to_csvto_pdf方法!",那么你的整个前提都是错的,毕竟你没有to_html方法,是吗?然而你的对象经常被呈现为HTML.考虑创建一个新的类来生成输出,而不是让数据模型知道CSV是什么(because it shouldn’t).

至于在模型中使用ActiveModel验证错误的帮助程序,很抱歉,ActiveModel/Rails迫使错误消息在数据层实现,而不是返回错误的语义idea,以供以后实现——sigh,这让我们都陷入困境.你可以绕过这个问题,但它基本上意味着不再使用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

Ruby-on-rails相关问答推荐

关于关联 has_many 的多级/三重嵌套形式

如何从数组中提取值

带有块捕获的 FormBuilder 辅助方法在 ERB 中不起作用

如何不需要rails/all?

ActiveRecord 错误地转义 JSON 字符串

为什么总是有东西在我的 mac 上的 5000 端口运行

错误 NoMethodError:ActionView::Base:Class 的未定义方法 `debug_rjs='

使用回形针进行简单裁剪

Rails 4,使用 ActiveRecord 的原始查询

不带参数的 request.fullpath

通过字符串获取 ActiveRecord 对象的属性

Rails Activeadmin - 自定义关联 Select 框

如何拯救 OmniAuth::Strategies::OAuth2::CallbackError?

Ruby 和 Ruby on Rails 离线 API 文档

Groovy/Grails :: Ruby/Rails :: 2011 框架状态

如何在 Ruby on Rails 的内存缓存存储中列出键?

有没有办法列出所有 belongs_to 关联?

您推荐哪些工具来分析 Rails 应用程序?

如何强制 RSpec 测试失败?

Date.current 和 Date.today 有什么区别?