Rieles: cómo usar un ayudante dentro de un controlador

207

Si bien me doy cuenta de que se supone que debes usar un ayudante dentro de una vista, necesito un ayudante en mi controlador ya que estoy construyendo un objeto JSON para regresar.

Va un poco así:

def xxxxx

   @comments = Array.new

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

   render :json => @comments
end

¿Cómo puedo acceder a mi html_formatayudante?

Un aprendiz
fuente
2
es posible que desee considerar la respuesta de @ grosser, es mucho más completa.
tokland
Sé que esto es viejo, pero ... ¿qué hay de malo en las clases de rubí simple? : p
Tarek

Respuestas:

205

Nota: Esto fue escrito y aceptado en los Rails 2 días; hoy en día la respuesta de Grosser es el camino a seguir.

Opción 1: Probablemente la forma más simple es incluir su módulo auxiliar en su 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

Opción 2: O puede declarar el método auxiliar como una función de clase, y usarlo así:

MyHelper.html_format(comment.content)

Si desea poder usarlo como una función de instancia y una función de clase, puede declarar ambas versiones en su ayudante:

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

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

¡Espero que esto ayude!

Xavier Holt
fuente
Gracias pero estoy un poco confundido. En este momento mi ayudante está en /app/helpers/application_helper.rb ... ¿Y me sugiere que mueva la ayuda a ApplicationController?
aprendiz
Agregué 'include ApplicationHelper' a mi application_controller pero esos errores con 'NoMethodError (método indefinido' html_format 'para ApplicationHelper: Módulo):'
AnApprentice
1
@AnApprentice Parece que lo has resuelto, pero modifiqué mi respuesta un poco, con suerte aclarando las cosas. En la primera versión, solo puede usar html_format, solo necesita MyHelper.html_formaten la segunda.
Xavier Holt
44
Esto no funciona cuando el método auxiliar que desea utilizar utiliza métodos de visualización como link_to. Los controladores no tienen acceso a estos métodos y la mayoría de mis ayudantes los utilizan. Además, incluir el ayudante en el controlador expone todos los métodos del ayudante como acciones de acceso público, lo que no es bueno. view_contextes el camino a seguir en Rails 3.
GregT
@GregT: no había visto la respuesta de Grosser antes, ya que apareció un poco después del hecho, pero también me gusta más. Acaba de recibir mi voto a favor.
Xavier Holt
304

Puedes usar

  • helpers.<helper>en rieles 5+ (o ActionController::Base.helpers.<helper>)
  • view_context.<helper>( Rieles 4 y 3 ) (ADVERTENCIA: esto crea una nueva instancia de vista por llamada)
  • @template.<helper>( Rieles 2 )
  • incluir ayudante en una clase singleton y luego singleton.helper
  • include el ayudante en el controlador (ADVERTENCIA: convertirá todos los métodos de ayuda en acciones del controlador)
más asqueroso
fuente
56
¡Esta respuesta es aún mejor! En los rieles 3, simplemente llamar view_context.helper_functiones simple y funciona muy bien. ActionController::Base.helpers.helper_functionEs igual de bueno.
trisweb
29
view_context= genio
n_i_c_k
55
ADVERTENCIA: no utilizar view_context. Instanciará una nueva instancia de vista por llamada ...
fny
77
ActionController::Base.helpers.helper_functionno parece funcionar Me aparece NoMethodError - undefined method spell_date_and_time' for #<ActionView::Base:0x007fede56102d0>:cuando intento llamar ActionController::Base.helpers.spell_date_and_time()a un método controlador. view_context.spell_date_and_time()Sin embargo, llamar funciona.
Bagre
37
rieles 5: simplemente utilícelos helpers.helper_functionen su controlador ( github.com/rails/rails/pull/24866 )
Markus
80

En Rails 5 use el helpers.helper_functionen su controlador.

Ejemplo:

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

Fuente: De un comentario de @Markus sobre una respuesta diferente. Sentí que su respuesta merecía su propia respuesta, ya que es la solución más limpia y fácil.

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

Gerry Shaw
fuente
66
Se siente un poco extraño que en la consola llamarías helperen singular y en el controlador es plural.
Compañero extraño
10

Mi problema se resolvió con la Opción 1. Probablemente la forma más simple es incluir su módulo auxiliar en su controlador:

class ApplicationController < ActionController::Base
  include ApplicationHelper

...
Thadeu Esteves Jr.
fuente
1
El único inconveniente es que agrega acciones de controlador con el nombre de las funciones auxiliares. Pero tbh, yo también hago eso :)
Felix
9

En general, si el ayudante se va a usar en (solo) controladores, prefiero declararlo como un método de instancia de class ApplicationController.

Franco
fuente
55
Como método protegido
Benjamin Crouzier
3

En Rails 5+ puedes simplemente usar la función como se muestra a continuación con un ejemplo 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

SALIDA

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

En Rails 5+ simplemente use helpers ( helpers.number_to_currency (10000) )

albertm
fuente