【问题标题】:Using helpers in model: how do I include helper dependencies?在模型中使用助手:如何包含助手依赖项?
【发布时间】:2010-10-04 03:06:17
【问题描述】:

我正在编写一个模型来处理来自文本区域的用户输入。根据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。为什么?我该怎么做才能解决这个问题?

【问题讨论】:

    标签: ruby-on-rails ruby activerecord model


    【解决方案1】:

    只需将第一行更改如下:

    include ActionView::Helpers
    

    这将使它工作。

    更新: 对于 Rails 3 使用:

    ActionController::Base.helpers.sanitize(str)
    

    归功于lornc's answer

    【讨论】:

    • 我自己说得再好不过了
    • 谢谢。我通过将包含移动到类定义内部来使其工作。
    • 有了这个我得到stack level too deep。它在 before_save 方法中。
    • 请不要将视图层问题与活动记录模型混为一谈。这是一种可怕的做法。更好的方法是在 AR 前面放置一个独立的输入数据净化器对象,并从中检索“干净”的属性。
    • 这是一个非常糟糕的解决方案,应该像火灾一样避免。 Rails 基于 MVC(Model View Controller)框架,其中 helper 位于 View 部分,因此您不应将 View Helper 方法与模型混合。
    【解决方案2】:

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

    ActionController::Base.helpers.sanitize(str)
    

    【讨论】:

    • 对于像我这样慢的人 - 你不需要包含任何东西,只需使用 ActionController::Base.helpers.sanitize("On the string you want to sanitize")
    • 谢谢,在 Rails 2.3.14 工作,而接受的答案没有。
    • 我向 application_helper 添加了一个方法,但我无法使用 Rails 3.0.3 使用 ActionController::Base.helpers.my_method(options) 从模型访问它?
    【解决方案3】:

    这对我来说效果更好:

    简单:

    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

    【讨论】:

    • ApplicationController.master_helper_module 在 Rails 3 和 4 中不再存在。 ApplicationController.helpers 是一个不错的选择。
    • 我投了这个票(简单的选项),因为它适合我的需要——我只需要一个助手,它使用 ApplicationController 中的前置过滤器保存的信息,所以在我的情况下,使关联显式是一个提醒有一个耦合。 [用例是多域应用程序,它通过模型通知器发出电子邮件,并带有返回应用程序的 url 链接 - 此 url 会根据 Web 请求的域而变化]
    【解决方案4】:

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

    OrdersController.helpers.order_number(@order)
    

    【讨论】:

    • 只使用ApplicationController.helpers.order_number(@order)。这意味着order_number 位于Order Helper
    • @rowanu 他说的是“从你自己的控制器中访问(帮助者)”,而不是“从你自己的控制器中访问帮助者”。
    【解决方案5】:

    如果你想在模型中使用my_helper_method,你可以这样写:

    ApplicationController.helpers.my_helper_method
    

    【讨论】:

      【解决方案6】:

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

      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
      

      【讨论】:

        猜你喜欢
        • 2020-03-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多