モデルでヘルパーを使用する:ヘルパーの依存関係を含めるにはどうすればよいですか?


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が見つかりません。どうして?これを修正するにはどうすればよいですか?

回答:


133

次のように最初の行を変更するだけです。

include ActionView::Helpers

それはそれを動作させるでしょう。

更新: Rails 3の場合:

ActionController::Base.helpers.sanitize(str)

クレジットはlorncの答えに行きます


自分でもっと上手く言えなかったはずです
Tilendor

1
ありがとう。includeをクラス定義の内部に移動することで機能しました。
O. Frabjous-Dey

1
これで私は得るstack level too deep。before_saveメソッドにあります。
Automatico

42
ビューレイヤーの問題とアクティブレコードモデルを混在させないでください。それはひどい習慣です。はるかに優れたアプローチは、スタンドアロン入力データサニタイザーオブジェクトをARの前に置き、そこから「クリーン」属性を取得することです。
solnic 2014

1
これは非常に悪い解決策であり、火のように避けるべきです。RailsはMVC(Model View Controller)フレームワークに基づいており、ヘルパーはビュー部分に含まれるため、ビューヘルパーメソッドとモデルを混在させないでください。
jedi

132

これにより、すべてのActionView :: Helpersメソッドをモデルにロードするという副作用のないヘルパーメソッドのみが提供されます。

ActionController::Base.helpers.sanitize(str)

6
私のような遅い人のために-あなたは何も含める必要はありません、ただActionController :: Base.helpers.sanitize( "On the you string to you sanitize")
Edward

ありがとう、Rails 2.3.14で作業しましたが、受け入れられた回答は機能しませんでした。
ChrisInEdmonton 2012年

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しかし素晴らしいものです。
Samuel

私はこれに投票しました(単純なオプション)。これは自分のニーズに合ったためです。ApplicationControllerのbeforeフィルターによって保存された情報を使用するヘルパーが1つだけ必要なので、関連付けを明示的にすると、結合があることを思い出します。[使用例はマルチドメインアプリであり、アプリに戻るURLリンクを含むモデル通知機能を介してメールを発行します-このURLはWebリクエストのドメインに応じて変化します]
iheggie

24

独自のコントローラーからヘルパーにアクセスするには、以下を使用します。

OrdersController.helpers.order_number(@order)

2
だけを使用しApplicationController.helpers.order_number(@order)ます。つまり、order_number位置はOrder Helper
次のとおりでし

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.