2009-01-28 12 views
78

Piszę model, który obsługuje dane wejściowe użytkownika z obszaru tekstowego. Postępując zgodnie z radą http://blog.caboo.se/articles/2008/8/25/sanitize-your-users-html-input, wyczyszczę dane wejściowe w modelu przed zapisaniem w bazie danych, używając wywołania zwrotnego before_validate.Korzystanie z helperów w modelu: jak dołączyć zależności pomocnicze?

Odpowiednie części mojego modelu wyglądać tak:

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 

trzeba dodawać, że to nie działa. Podczas próby zapisania nowego posta pojawia się następujący błąd.

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

Najwyraźniej SanitizeHelper tworzy instancję HTML :: WhiteListSanitizer, ale kiedy wymieszać ją do mojego modelu nie może znaleźć HTML :: WhiteListSanitizer. Czemu? Co mogę zrobić, aby to naprawić?

Odpowiedz

109

Wystarczy zmienić pierwszą linię następująco:

include ActionView::Helpers 

że uczyni to działa.

UPDATE: dla szyn 3 Zastosowanie:

ActionController::Base.helpers.sanitize(str) 

zasługa lornc's answer

+0

nie mógł powiedzieć, że lepiej sobie – Tilendor

+1

Dzięki. Mam go do pracy, przenosząc dołączyć do wewnątrz definicji klasy. –

+1

Dzięki temu otrzymuję 'poziom stosu za głęboki'. Jest w metodzie before_save. – Automatico

121

To daje tylko metody pomocnika bez skutków ubocznych związanych z załadunkiem każdy actionView :: metoda pomocnicy do swojego modelu :

ActionController::Base.helpers.sanitize(str) 
+4

To działało w Rails 3, podczas gdy akceptowane rozwiązanie nie. –

+6

Dla zwolenników takich jak ja - nie musisz niczego włączać, po prostu użyj ActionController :: Base.helpers.sanitize ("Na strunę, którą chcesz dezynfekować") – Edward

+0

Dziękuję, pracowałeś w Railsach 2.3.14, podczas gdy zaakceptowana odpowiedź nie. – ChrisInEdmonton

22

Aby uzyskać dostęp do pomocy z własnych kontrolerów, wystarczy użyć:

OrdersController.helpers.order_number(@order) 
+3

Pytanie dotyczy modeli, nie kontrolerów – rowanu

+4

To samo dotyczy modeli. – Tarmo

+2

Po prostu używając 'ApplicationController.helpers.order_number (@order)'. Oznacza to, że 'order_number' był zlokalizowany na' Order Helper' – ksugiarto

9

Nie polecam żadnej z tych metod. Zamiast tego umieść go w swoim własnym obszarze nazw.

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 
22

Działa to lepiej dla mnie:

Proste:

ApplicationController.helpers.my_helper_method 

Advance:

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 

Źródło: http://makandracards.com/makandra/1307-how-to-use-helper-methods-inside-a-model

+0

Moduł 'ApplicationController.master_helper_module' już nie istnieje w Railsach 3 i 4 pojawia się. "ApplicationController.helpers" jest jednak fajny. – Samuel

+0

Głosowałem za tym (opcja prosta), ponieważ odpowiadało moim potrzebom - potrzebuję tylko jednego pomocnika, który używa informacji zapisanych przez filtr przed w aplikacji ApplicationController, więc w moim przypadku wyraźne skojarzenie jest przypomnieniem, że istnieje sprzężenie. [Przypadek użycia to aplikacja w wielu domenach, która wysyła e-maile za pośrednictwem zgłaszającego model z linkiem do strony z powrotem do aplikacji - adres ten zmienia się w zależności od domeny żądania internetowego] – iheggie

+0

Dzięki chłopaki! ;RE – skozz

2

Jeśli chcesz użyć my_helper_method helper_method wewnątrz modelu, można napisać:

ApplicationController.helpers.my_helper_method 
Powiązane problemy