Utilizzo degli helper nel modello: come includo le dipendenze dell'helper?


100

Sto scrivendo un modello che gestisce l'input dell'utente da un'area di testo. Seguendo il consiglio di http://blog.caboo.se/articles/2008/8/25/sanitize-your-users-html-input , sto ripulendo l'input nel modello prima di salvare nel database, utilizzando before_validate richiama.

Le parti rilevanti del mio modello hanno questo aspetto:

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

Inutile dire che questo non funziona. Ricevo il seguente errore quando provo a salvare un nuovo post.

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

Apparentemente, SanitizeHelper crea un'istanza di HTML :: WhiteListSanitizer, ma quando lo mischio nel mio modello non riesce a trovare HTML :: WhiteListSanitizer. Perché? Cosa posso fare per risolverlo?

Risposte:


133

Basta cambiare la prima riga come segue:

include ActionView::Helpers

quello lo farà funzionare.

AGGIORNAMENTO: per Rails 3 utilizzare:

ActionController::Base.helpers.sanitize(str)

Il merito va alla risposta di lornc


non avrei potuto dirlo meglio io stesso
Tilendor

1
Grazie. Ho funzionato spostando l'inclusione all'interno della definizione della classe.
O. Frabjous-Dey

1
Con questo ottengo stack level too deep. È in un metodo before_save.
Automatico

42
Si prega di non mescolare le preoccupazioni del livello di visualizzazione con i modelli di record attivi. È una pratica terribile. Un approccio molto migliore consiste nel mettere un oggetto disinfettante di dati di input autonomo davanti a AR e recuperare gli attributi "puliti" da esso.
solnico

1
Questa è una pessima soluzione e dovrebbe essere evitata come il fuoco. Rails si basa sul framework MVC (Model View Controller) in cui l'helper è disponibile nella parte View, quindi non dovresti mescolare i metodi di view helper con il modello.
jedi

132

Questo ti dà solo il metodo helper senza gli effetti collaterali del caricamento di ogni metodo ActionView :: Helpers nel tuo modello:

ActionController::Base.helpers.sanitize(str)

6
Per le persone lente come me - non è necessario includere nulla, usa semplicemente ActionController :: Base.helpers.sanitize ("Sulla stringa che vuoi disinfettare")
Edward

Grazie, ha lavorato in Rails 2.3.14 mentre la risposta accettata no.
ChrisInEdmonton

Ho aggiunto un metodo a application_helper, ma non sono riuscito ad accedervi dal modello usando ActionController :: Base.helpers.my_method (opzioni) usando Rails 3.0.3?
Tom Rossi

35

Questo funziona meglio per me:

Semplice:

ApplicationController.helpers.my_helper_method

Progredire:

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

Fonte: http://makandracards.com/makandra/1307-how-to-use-helper-methods-inside-a-model


1
Il ApplicationController.master_helper_modulenon esiste più in Rails 3 e 4 appare. Comunque ApplicationController.helpersè carino.
Samuel

Ho votato per questa (l'opzione semplice) perché si adatta alle mie esigenze: ho solo bisogno di un aiutante che utilizza le informazioni salvate da un filtro before in ApplicationController, quindi nel mio caso rendere esplicita l'associazione è un promemoria che c'è un accoppiamento. [Il caso d'uso è un'app multi dominio, che invia e-mail tramite un notificatore di modello con un collegamento URL all'app - questo URL cambia a seconda del dominio della richiesta web]
iheggie

24

Per accedere agli helper dai tuoi controller, usa semplicemente:

OrdersController.helpers.order_number(@order)

2
Sto solo usando ApplicationController.helpers.order_number(@order). Ciò significa che order_numberera localizzato suOrder Helper
ksugiarto

3
@rowanu Sta dicendo "per accedere a (helper dai tuoi controllori)", non "(per accedere agli helper) dai tuoi controllori".
Ajedi32

11

Non consiglierei nessuno di questi metodi. Invece, inseriscilo nel suo spazio dei nomi.

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

Se vuoi usare l' my_helper_methodinterno di un modello puoi scrivere:

ApplicationController.helpers.my_helper_method
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.