Rails - Como usar um auxiliar dentro de um controlador

207

enquanto eu percebo que você deve usar um auxiliar dentro de uma exibição, preciso de um auxiliar no meu controlador enquanto estou construindo um objeto JSON para retornar.

É um pouco assim:

def xxxxx

   @comments = Array.new

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

   render :json => @comments
end

como posso acessar meu html_formatajudante?

Um aprendiz
fonte
2
você pode considerar a resposta do @ grosser's, é muito mais completa.
tokland
Eu sei que isso é antigo, mas ... o que há de errado com as classes simples de rubi? : p
Tarek

Respostas:

205

Nota: Isso foi escrito e aceito nos 2 dias do Rails; hoje a resposta mais grosseira é o caminho a percorrer.

Opção 1: Provavelmente a maneira mais simples é incluir o módulo auxiliar no seu controlador:

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

Opção 2: Ou você pode declarar o método auxiliar como uma função de classe e usá-lo da seguinte forma:

MyHelper.html_format(comment.content)

Se você quiser usá-lo como uma função de instância e uma função de classe, poderá declarar as duas versões no seu auxiliar:

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

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

Espero que isto ajude!

Xavier Holt
fonte
Obrigado, mas estou um pouco confuso. No momento, meu assistente está em /app/helpers/application_helper.rb ... E você está sugerindo que eu deva mover o auxiliar para ApplicationController?
AnApprentice
Eu adicionei 'include ApplicationHelper' ao meu application_controller, mas que erros com 'NoMethodError (método indefinido `html_format' para ApplicationHelper: Module): '
AnApprentice
1
@AnApprentice Parece que você já descobriu, mas ajustei um pouco minha resposta, espero tornar as coisas mais claras. Na primeira versão, você pode apenas usar html_format- você só precisa MyHelper.html_formatna segunda.
Xavier Holt
4
Isso não funciona quando o método auxiliar que você deseja usar utiliza métodos de exibição como link_to. Os controladores não têm acesso a esses métodos e a maioria dos meus ajudantes usa esses métodos. Além disso, incluir o auxiliar no controlador expõe todos os métodos do auxiliar como ações acessíveis ao público, o que não é bom. view_contexté o caminho a percorrer no Rails 3.
GregT
@ GregT - Não tinha visto a resposta do grosser antes, pois veio um pouco depois do fato, mas eu também gosto mais. Ele acabou de receber o meu voto.
Xavier Holt
304

Você pode usar

  • helpers.<helper>no Rails 5+ (ou ActionController::Base.helpers.<helper>)
  • view_context.<helper>( Rails 4 e 3 ) (AVISO: instancia uma nova instância de visualização por chamada)
  • @template.<helper>( Trilhos 2 )
  • inclua ajudante em uma classe singleton e depois singleton.helper
  • include o auxiliar no controlador (AVISO: transformará todos os métodos auxiliares em ações do controlador)
mais grosseiro
fonte
56
Esta resposta é ainda melhor! No Rails 3, simplesmente chamar view_context.helper_functioné simples e funciona muito bem. ActionController::Base.helpers.helper_functioné igualmente bom.
trisweb
29
view_context= genius
n_i_c_k
5
AVISO: Não use view_context.
Instanciará
7
ActionController::Base.helpers.helper_functionparece não funcionar. Recebo NoMethodError - undefined method spell_date_and_time' for #<ActionView::Base:0x007fede56102d0>:ao tentar chamar ActionController::Base.helpers.spell_date_and_time()um método de controlador. chamar view_context.spell_date_and_time()funciona no entanto.
Catfish
37
Trilhos 5: basta usar helpers.helper_functionem seu controlador ( github.com/rails/rails/pull/24866 )
Markus
80

No Rails 5, use o helpers.helper_functionno seu controlador.

Exemplo:

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

Fonte: De um comentário de @Markus em uma resposta diferente. Eu senti que a resposta dele merecia sua própria resposta, já que é a solução mais limpa e fácil.

Referência: https://github.com/rails/rails/pull/24866

Gerry Shaw
fonte
6
Parece um pouco estranho que no console você chamaria helperno singular e no controlador é plural.
Companheiro Estrangeiro
10

Meu problema foi resolvido com a opção 1. Provavelmente, a maneira mais simples é incluir o módulo auxiliar no seu controlador:

class ApplicationController < ActionController::Base
  include ApplicationHelper

...
Thadeu Esteves Jr.
fonte
1
A única desvantagem é que ele adiciona ações do controlador com o nome das funções auxiliares. Mas TBH, eu faço isso, também :)
Felix
9

Em geral, se o auxiliar for usado em (apenas) controladores, prefiro declará-lo como um método de instância de class ApplicationController.

Franco
fonte
5
Como método protegido
Benjamin Crouzier
3

No Rails 5+, você pode simplesmente usar a função conforme demonstrado abaixo com um exemplo simples:

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

RESULTADO

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

No Rails 5+, basta usar helpers ( helpers.number_to_currency (10000) )

albertm
fonte