Rails - Comment utiliser un assistant dans un contrôleur

207

bien que je réalise que vous êtes censé utiliser un assistant dans une vue, j'ai besoin d'un assistant dans mon contrôleur car je construis un objet JSON pour revenir.

Ça va un peu comme ça:

def xxxxx

   @comments = Array.new

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

   render :json => @comments
end

comment puis-je accéder à mon html_formatassistant?

Un apprenti
la source
2
vous voudrez peut-être considérer la réponse de @ grosser, elle est beaucoup plus complète.
tokland
Je sais que c'est vieux mais ... qu'est-ce qui ne va pas avec les cours de rubis uni? : p
Tarek

Réponses:

205

Remarque: cela a été écrit et accepté dans les Rails 2 jours; de nos jours, la réponse de Grosser est la voie à suivre.

Option 1: le moyen le plus simple consiste probablement à inclure votre module d'assistance dans votre contrôleur:

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

Option 2: Ou vous pouvez déclarer la méthode d'assistance en tant que fonction de classe et l'utiliser comme ceci:

MyHelper.html_format(comment.content)

Si vous voulez pouvoir l'utiliser à la fois comme fonction d'instance et fonction de classe, vous pouvez déclarer les deux versions dans votre assistant:

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

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

J'espère que cela t'aides!

Xavier Holt
la source
Merci mais je suis un peu confus. En ce moment, mon aide se trouve dans /app/helpers/application_helper.rb ... ET vous proposez que je devrais déplacer l'aide vers ApplicationController?
AnApprentice
J'ai ajouté 'include ApplicationHelper' à mon application_controller mais cette erreur avec 'NoMethodError (méthode non définie `html_format' pour ApplicationHelper: Module): '
AnApprentice
1
@AnApprentice On dirait que vous l'avez compris, mais j'ai peaufiné ma réponse un peu, j'espère que les choses sont plus claires. Dans la première version, vous pouvez simplement utiliser html_format- vous n'avez besoin que MyHelper.html_formatdans la seconde.
Xavier Holt
4
Cela ne fonctionne pas lorsque la méthode d'assistance que vous souhaitez utiliser utilise des méthodes d'affichage telles que link_to. Les contrôleurs n'ont pas accès à ces méthodes et la plupart de mes assistants utilisent ces méthodes. En outre, l'inclusion de l'aide dans le contrôleur expose toutes les méthodes de l'aide en tant qu'actions accessibles au public, ce qui n'est pas bon. view_contextest le chemin à parcourir dans Rails 3.
GregT
@GregT - Je n'avais pas vu la réponse de Grosser auparavant, car elle est arrivée un peu après le fait, mais je l'aime mieux aussi. Il vient de recevoir mon vote positif.
Xavier Holt
304

Vous pouvez utiliser

  • helpers.<helper>dans Rails 5+ (ou ActionController::Base.helpers.<helper>)
  • view_context.<helper>( Rails 4 et 3 ) (AVERTISSEMENT: cela instancie une nouvelle instance de vue par appel)
  • @template.<helper>( Rails 2 )
  • inclure un assistant dans une classe singleton, puis singleton.helper
  • include l'assistant dans le contrôleur (ATTENTION: transformera toutes les méthodes d'aide en actions du contrôleur)
plus grossier
la source
56
Cette réponse est encore meilleure! Dans les rails 3, simplement appeler view_context.helper_functionest simple et fonctionne très bien. ActionController::Base.helpers.helper_functionest tout aussi bon.
trisweb
29
view_context= génie
n_i_c_k
5
AVERTISSEMENT: ne pas utiliser view_context. Il instanciera une nouvelle instance de vue par appel ...
fny
7
ActionController::Base.helpers.helper_functionne semble pas fonctionner. J'obtiens NoMethodError - undefined method spell_date_and_time' for #<ActionView::Base:0x007fede56102d0>:en essayant d'appeler ActionController::Base.helpers.spell_date_and_time()une méthode de contrôleur. appeler view_context.spell_date_and_time()fonctionne cependant.
Catfish
37
rails 5: utilisez simplement helpers.helper_functiondans votre contrôleur ( github.com/rails/rails/pull/24866 )
Markus
80

Dans Rails 5, utilisez le helpers.helper_functiondans votre contrôleur.

Exemple:

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

Source: D'après un commentaire de @Markus sur une réponse différente. J'ai senti que sa réponse méritait sa propre réponse car c'est la solution la plus propre et la plus facile.

Référence: https://github.com/rails/rails/pull/24866

Gerry Shaw
la source
6
Cela fait un peu bizarre que dans la console, vous appeliez helperau singulier et dans le contrôleur, c'est pluriel.
Fellow Stranger
10

Mon problème a été résolu avec l'option 1. Le moyen le plus simple est probablement d'inclure votre module d'assistance dans votre contrôleur:

class ApplicationController < ActionController::Base
  include ApplicationHelper

...
Thadeu Esteves Jr.
la source
1
Seul inconvénient, il ajoute des actions de contrôleur avec le nom des fonctions d'assistance. Mais tbh, je fais ça aussi :)
Felix
9

En général, si l'aide doit être utilisée dans (simplement) des contrôleurs, je préfère la déclarer comme méthode d'instance de class ApplicationController.

Franco
la source
5
Comme méthode protégée
Benjamin Crouzier
3

Dans Rails 5+, vous pouvez simplement utiliser la fonction comme illustré ci-dessous avec un exemple simple:

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

PRODUCTION

"2018-12-10 01:01 AM"
Ravistm
la source
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

Dans Rails 5+, utilisez simplement des aides ( helpers.number_to_currency (10000) )

Albert
la source