Використання помічників у моделі: як я включаю допоміжні залежності?


100

Я пишу модель, яка обробляє введення користувача з текстової області. Виконуючи поради http://blog.caboo.se/articles/2008/8/25/sanitize-your-users-html-input , я очищаю вхід в моделі перед збереженням у базі даних, використовуючи попередній_валіdate зворотний дзвінок

Відповідні частини моєї моделі виглядають так:

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


Я не міг би сказати цього краще
Тилендор,

1
Дякую. Я змусив його працювати, перемістивши include у внутрішнє визначення класу.
О. Фрабжоус-Дей

1
З цим я отримую stack level too deep. Це в методі до_захисту.
Automatico

42
Будь ласка, не змішуйте проблеми шару перегляду з активними моделями запису. Це жахлива практика. Набагато кращий підхід полягає в тому, щоб поставити окремий об'єкт дезіннізації вхідних даних перед AR та отримати з нього "чисті" атрибути.
solnic

1
Це дуже погане рішення, і його слід уникати, як пожежу. Rails базується на структурі MVC (Model View Controller), де помічник входить у програму View, тому не слід змішувати допоміжні методи перегляду з моделлю.
джеді

132

Це дає вам лише допоміжний метод без побічних ефектів завантаження кожного методу ActionView :: Helpers у вашу модель:

ActionController::Base.helpers.sanitize(str)

6
Для тих повільних людей, як я - вам нічого не потрібно включати, просто використовуйте ActionController :: Base.helpers.sanitize ("На рядок, який ви хочете оздоровити")
Едвард

Дякую, працювали в Rails 2.3.14, поки прийнятої відповіді не було.
ChrisInEdmonton

Я додав метод у application_helper, але мені не вдалося отримати доступ до нього з моделі за допомогою ActionController :: Base.helpers.my_method (варіанти) за допомогою Rails 3.0.3?
Том Россі

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_moduleRails 3 і 4 це більше не існує. ApplicationController.helpersХороший один , хоча.
Самуїл

Я проголосував за це (простий варіант), тому що він відповідав моїм потребам - мені потрібен лише один помічник, який використовує інформацію, збережену фільтром до в програмі ApplicationController, тому в моєму випадку зробити об'єднання явним - це нагадування про наявність зв'язку. [Використовуйте випадок - це багатодоменне додаток, яке видає електронні листи через модельний сповіщувач із посиланням URL на додаток - ця URL-адреса змінюється залежно від домену веб-запиту]
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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.