Рейки - Як користуватися помічником всередині контролера


207

Хоча я усвідомлюю, що ви повинні використовувати помічник всередині подання, мені потрібен помічник у контролері, оскільки я будую об’єкт JSON для повернення.

Це виглядає трохи так:

def xxxxx

   @comments = Array.new

   @c_comments.each do |comment|
   @comments << {
     :id => comment.id,
     :content => html_format(comment.content)
   }
   end

   render :json => @comments
end

як я можу отримати доступ до свого html_formatпомічника?


2
ви можете розглянути відповідь @ grosser, вона набагато повніша.
tokland

Я знаю, що це по-старому, але ... що не так із звичайними рубіновими класами? : p
Тарек

Відповіді:


205

Примітка. Це було написано та прийнято ще через 2 дні; нині відповідь гроссера - це шлях.

Варіант 1: Мабуть, найпростіший спосіб - включити свій контрольний модуль у свій контролер:

class MyController < ApplicationController
  include MyHelper

  def xxxx
    @comments = []
    Comment.find_each do |comment|
      @comments << {:id => comment.id, :html => html_format(comment.content)}
    end
  end
end

Варіант 2: Або ви можете оголосити метод помічника як функцію класу та використовувати його так:

MyHelper.html_format(comment.content)

Якщо ви хочете мати можливість використовувати його як функцію екземпляра, так і функцію класу, ви можете оголосити обидві версії у своєму помічнику:

module MyHelper
  def self.html_format(str)
    process(str)
  end

  def html_format(str)
    MyHelper.html_format(str)
  end
end

Сподіваюсь, це допомагає!


Дякую, але я трохи розгублений. Зараз мій помічник перебуває у /app/helpers/application_helper.rb ... І ви пропонуєте мені перенести помічника на ApplicationController?
AnApprentice

Я додав "включити ApplicationHelper" до свого application_controller, але помилки з "NoMethodError (невизначений метод` html_format 'для ApplicationHelper: Модуль):'
AnApprentice

1
@AnApprentice Схоже, ви це зрозуміли, але я трохи змінив свою відповідь, сподіваюся, що все стане зрозумілішим. У першій версії ви можете просто використовувати html_format- вам потрібно лише MyHelper.html_formatу другій.
Ксав'є Холт

4
Це не працює, коли в якості допоміжного методу ви хочете використовувати методи перегляду, такі як link_to. Контролери не мають доступу до цих методів, і більшість моїх помічників використовують ці методи. Крім того, включення помічника в контролер розкриває всі методи помічників як загальнодоступні дії, що не є добре. view_contextце шлях в Rails 3.
GregT

@GregT - Я раніше не бачив відповіді гроссера, оскільки він з’явився трохи після факту, але мені це теж подобається. Він щойно отримав мою пропозицію.
Ксав'є Холт

304

Можна використовувати

  • helpers.<helper>в Rails 5+ (або ActionController::Base.helpers.<helper>)
  • view_context.<helper>( Rails 4 і 3 ) (УВАГА: це створює новий екземпляр перегляду за викликом)
  • @template.<helper>( Рейки 2 )
  • включити помічника в клас одиночки, а потім singleton.helper
  • include помічник у контролері (ПОПЕРЕДЖЕННЯ: перетворить усі допоміжні методи в дії контролера)

56
Ця відповідь ще краща! У рейках 3 просто дзвонити view_context.helper_functionпросто і чудово працює. ActionController::Base.helpers.helper_functionоднаково добре.
trisweb

29
view_context= геній
n_i_c_k

5
УВАГА: Не використовуйте view_context. Це
створить

7
ActionController::Base.helpers.helper_functionСхоже, не працює. Я отримую NoMethodError - undefined method spell_date_and_time' for #<ActionView::Base:0x007fede56102d0>:при спробі виклику ActionController::Base.helpers.spell_date_and_time()методом контролера. дзвінок view_context.spell_date_and_time()дійсно працює.
Сом

37
рейли 5: просто використовуйте helpers.helper_functionу своєму контролері ( github.com/rails/rails/pull/24866 )
Маркус

80

У Rails 5 використовуйте helpers.helper_functionу своєму контролері.

Приклад:

def update
  # ...
  redirect_to root_url, notice: "Updated #{helpers.pluralize(count, 'record')}"
end

Джерело: З коментаря @Markus до іншої відповіді. Я відчув, що його відповідь заслужив власну відповідь, оскільки це найчистіше і простіше рішення.

Довідка: https://github.com/rails/rails/pull/24866


6
Відчувається трохи дивним, що в консолі ви телефонуєте helperв однині, а в контролері - множині.
Непознаний незнайомець

10

Моя проблема вирішена з варіантом 1. Напевно, найпростіший спосіб - включити свій контрольний модуль у свій контролер:

class ApplicationController < ActionController::Base
  include ApplicationHelper

...

1
Тільки недоліком є ​​те, що він додає дії контролера з назвою допоміжних функцій. Але tbh, я теж це роблю :)
Фелікс

9

Взагалі, якщо помічник потрібно використовувати в (просто) контролерах, я вважаю за краще оголосити його як метод екземпляра class ApplicationController.


5
Як захищений метод
Бенджамін Крузьє,

3

У Rails 5+ ви можете просто використовувати функцію, як показано нижче, простим прикладом:

module ApplicationHelper
  # format datetime in the format #2018-12-01 12:12 PM
  def datetime_format(datetime = nil)
    if datetime
      datetime.strftime('%Y-%m-%d %H:%M %p')
    else
      'NA'
    end
  end
end

class ExamplesController < ApplicationController
  def index
    current_datetime = helpers.datetime_format DateTime.now
    raise current_datetime.inspect
  end
end

ВИХІД

"2018-12-10 01:01 AM"

0
class MyController < ApplicationController
    # include your helper
    include MyHelper
    # or Rails helper
    include ActionView::Helpers::NumberHelper

    def my_action
      price = number_to_currency(10000)
    end
end

У Rails 5+ просто використовуйте helpers ( helpers.number_to_currency (10000) )

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