Szyny - jak korzystać z pomocnika wewnątrz kontrolera

207

chociaż zdaję sobie sprawę, że powinieneś używać pomocnika w widoku, potrzebuję pomocnika w moim kontrolerze, gdy buduję obiekt JSON do zwrócenia.

Wygląda to trochę tak:

def xxxxx

   @comments = Array.new

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

   render :json => @comments
end

jak mogę uzyskać dostęp do mojego html_formatpomocnika?

Uczeń
źródło
2
możesz rozważyć odpowiedź @ grosser, jest ona o wiele bardziej kompletna.
tokland
Wiem, że to stare, ale ... co jest nie tak z zwykłymi klasami ruby? : p
Tarek

Odpowiedzi:

205

Uwaga: Zostało to napisane i zaakceptowane w Railsach 2 dni; W dzisiejszych czasach odpowiedź Grossera jest właściwą drogą.

Opcja 1: Prawdopodobnie najprostszym sposobem jest włączenie modułu pomocniczego do kontrolera:

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

Opcja 2: Lub możesz zadeklarować metodę pomocniczą jako funkcję klasy i użyć jej w następujący sposób:

MyHelper.html_format(comment.content)

Jeśli chcesz móc używać go zarówno jako funkcji instancji, jak i funkcji klasy, możesz zadeklarować obie wersje w pomocniku:

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

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

Mam nadzieję że to pomoże!

Xavier Holt
źródło
Dzięki, ale jestem trochę zdezorientowany. Obecnie mój pomocnik znajduje się w /app/helpers/application_helper.rb ... A sugerujesz, że powinienem przenieść pomocnika do ApplicationController?
AnApprentice
Dodałem „include ApplicationHelper” do mojego application_controller, ale to błędy z „NoMethodError (niezdefiniowana metoda„ html_format ”dla ApplicationHelper: Module):”
AnApprentice
1
@AnApprentice Wygląda na to, że to rozgryzłeś, ale poprawiłem nieco moją odpowiedź, mam nadzieję, że wszystko wyjaśni się. W pierwszej wersji możesz po prostu użyć html_format- potrzebujesz tylko MyHelper.html_formatw drugiej.
Xavier Holt
4
Nie działa to, gdy metoda pomocnicza, której chcesz użyć, korzysta z metod widoku takich jak link_to. Kontrolery nie mają dostępu do tych metod i większość moich pomocników używa tych metod. Również włączenie pomocnika do kontrolera ujawnia wszystkie metody pomocnika jako publicznie dostępne działania, co nie jest dobre. view_contextjest drogą do przejścia w Rails 3.
GregT
@GregT - Nie widziałem wcześniej odpowiedzi Grossera, ponieważ pojawiła się nieco później, ale ja też bardziej mi się podoba. Właśnie dostał moją opinię.
Xavier Holt,
304

Możesz użyć

  • helpers.<helper>w Railsach 5+ (lub ActionController::Base.helpers.<helper>)
  • view_context.<helper>( Szyny 4 i 3 ) (OSTRZEŻENIE: tworzy instancję nowego wystąpienia widoku dla każdego połączenia)
  • @template.<helper>( Szyny 2 )
  • dołączyć pomocnika do klasy singleton, a następnie singleton.helper
  • include pomocnik w kontrolerze (OSTRZEŻENIE: przekształci wszystkie metody pomocnika w akcje kontrolera)
grosser
źródło
56
Ta odpowiedź jest jeszcze lepsza! W szynach 3 zwykłe dzwonienie view_context.helper_functionjest proste i działa świetnie. ActionController::Base.helpers.helper_functionjest równie dobry.
trisweb,
29
view_context= geniusz
n_i_c_k
5
OSTRZEŻENIE: Nie używaj view_context. Utworzy nową instancję widoku dla każdego połączenia ...
fny
7
ActionController::Base.helpers.helper_functionwydaje się nie działać. Pojawia się, NoMethodError - undefined method spell_date_and_time' for #<ActionView::Base:0x007fede56102d0>:gdy próbuję wywołać ActionController::Base.helpers.spell_date_and_time()metodę kontrolera. dzwonienie view_context.spell_date_and_time()jednak działa.
Sum
37
szyny 5: po prostu użyj helpers.helper_functionw swoim kontrolerze ( github.com/rails/rails/pull/24866 )
Markus
80

W Railsach 5 użyj helpers.helper_functionw swoim kontrolerze.

Przykład:

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

Źródło: Na podstawie komentarza @Markus na temat innej odpowiedzi. Czułem, że jego odpowiedź zasługuje na własną odpowiedź, ponieważ jest to najczystsze i łatwiejsze rozwiązanie.

Odniesienie: https://github.com/rails/rails/pull/24866

Gerry Shaw
źródło
6
Czuje się trochę dziwnie, że w konsoli można nazwać helperliczbę pojedynczą, a w kontrolerze liczbę mnogą.
Fellow Stranger
10

Mój problem rozwiązany w opcji 1. Prawdopodobnie najprostszym sposobem jest włączenie modułu pomocniczego do kontrolera:

class ApplicationController < ActionController::Base
  include ApplicationHelper

...
Thadeu Esteves Jr.
źródło
1
Jedynym minusem jest to, że dodaje akcje kontrolera z nazwą funkcji pomocnika. Ale tbh, też to robię :)
Felix
9

Ogólnie rzecz biorąc, jeśli pomocnik ma być używany w (tylko) kontrolerach, wolę zadeklarować go jako metodę instancji class ApplicationController.

Franco
źródło
5
Jako metoda chroniona
Benjamin Crouzier
3

W Railsach 5+ możesz po prostu użyć funkcji pokazanej poniżej na prostym przykładzie:

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

WYNIK

"2018-12-10 01:01 AM"
Ravistm
źródło
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

W Rails 5+ prostu użyć pomocników ( helpers.number_to_currency (10000) )

albertm
źródło