在模型中使用助手:如何包括助手依赖项?


100

我正在编写一个处理来自文本区域的用户输入的模型。遵循http://blog.caboo.se/articles/2008/8/25/sanitize-your-users-html-input的建议,我先使用before_validate清理模型中的输入,然后再保存到数据库中打回来。

我模型的相关部分如下所示:

include ActionView::Helpers::SanitizeHelper

class Post < ActiveRecord::Base {
  before_validation :clean_input

  ...

  protected

  def clean_input
    self.input = sanitize(self.input, :tags => %w(b i u))
  end
end

不用说,这是行不通的。尝试保存新帖子时出现以下错误。

undefined method `white_list_sanitizer' for #<Class:0xdeadbeef>

显然,SanitizeHelper创建了HTML :: WhiteListSanitizer的实例,但是当我将其混合到模型中时,找不到HTML :: WhiteListSanitizer。为什么?我该如何解决这个问题?

Answers:


133

只需更改第一行,如下所示:

include ActionView::Helpers

这将使其工作。

更新:对于Rails 3使用:

ActionController::Base.helpers.sanitize(str)

幸得lornc的答案


我自己都
说不出

1
谢谢。我通过将include移到类定义内部来使其工作。
O. Frabjous-Dey 2009年

1
有了这个我得到stack level too deep。它在before_save方法中。
Automatico

42
请不要将视图层问题与活动记录模型混合在一起。这是一个可怕的做法。更好的方法是将一个独立的输入数据清理器对象放在AR的前面,并从中检索“干净”属性。
solnic 2014年

1
这是一个非常糟糕的解决方案,应避免火灾。Rails基于MVC(模型视图控制器)框架,帮助器出现在视图部分,因此您不应将视图帮助器方法与模型混合使用。
jedi

132

这仅给您提供了辅助方法,而没有将每个ActionView :: Helpers方法加载到模型中的副作用:

ActionController::Base.helpers.sanitize(str)

6
对于像我这样的慢人-您不需要添加任何内容,只需使用ActionController :: Base.helpers.sanitize(“在要消毒的字符串上”)
Edward

谢谢,在Rails 2.3.14中工作,但没有接受。
克里斯·埃德蒙顿(ChrisInEdmonton)

我在application_helper中添加了一个方法,但是无法通过使用Rails 3.0.3的ActionController :: Base.helpers.my_method(options)从模型中访问它?
汤姆·罗西

35

这对我来说更好:

简单:

ApplicationController.helpers.my_helper_method

提前:

class HelperProxy < ActionView::Base
  include ApplicationController.master_helper_module

  def current_user
    #let helpers act like we're a guest
    nil
  end       

  def self.instance
    @instance ||= new
  end
end

资料来源:http//makandracards.com/makandra/1307-how-to-use-helper-methods-inside-a-model


1
ApplicationController.master_helper_module不存在任何更多的Rails 3和它出现4。虽然ApplicationController.helpers是一个不错的。
塞缪尔

我投票支持此选项(简单选项)是因为它适合我的需要-我只需要一个使用使用ApplicationController中的before过滤器保存的信息的助手,因此在我的情况下,使关联显式可以提醒我们存在耦合。[用例是多域应用程序,该应用程序通过模型通知程序发出带有指向应用程序的URL链接的电子邮件-该URL随Web请求的域而变化]
iheggie 2015年

24

要从您自己的控制器访问助手,只需使用:

OrdersController.helpers.order_number(@order)

2
只是使用ApplicationController.helpers.order_number(@order)。这表示该广告order_number位于Order Helper
ksugiarto

3
@rowanu他说的是“从您自己的控制器访问(帮助者)”,而不是“(从您自己的控制器访问帮助者)”。
Ajedi32

11

我不推荐任何这些方法。而是将其放在自己的名称空间中。

class Post < ActiveRecord::Base
  def clean_input
    self.input = Helpers.sanitize(self.input, :tags => %w(b i u))
  end

  module Helpers
    extend ActionView::Helpers::SanitizeHelper
  end
end

11

如果要my_helper_method在模型内部使用,可以编写:

ApplicationController.helpers.my_helper_method
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.