rubyonrails rails print logs help guide debugger ruby-on-rails model-view-controller filter

ruby-on-rails - rails - ruby print in console



Rieles: establezca una variable de instancia comĂșn en varias acciones del controlador (3)

En primer lugar, no desea intentar insertar el código "entre" una acción del controlador y una representación de plantilla. ¿Por qué? Porque desea que la acción del controlador tenga la libertad de elegir qué tipo de respuesta dar. Podría devolver XML, JSON, solo encabezados, una redirección, nada, etc. Es por eso que después de que se ejecutan los filtros después de que se haya procesado la respuesta.

En segundo lugar, no quieres parches Fixnum . Quiero decir, tal vez sí, pero no lo hago. No a menudo al menos, y no a menos que obtenga algunos beneficios semánticos totalmente perversos, como ser capaz de decir 3.blind_mice . El parche parcheado para un caso de uso aleatorio como este parece ser un dolor de cabeza de mantenimiento en el futuro.

Usted menciona refactorizar todo el código específico de la caja de los controladores en un filtro anterior y ejecutarlos secuencialmente. Lo que me @foo a la mente ... @foo es el mismo en todos los casos? Si ese es el caso, entonces uno antes del filtro funcionaría bien:

before_filter :do_common_stuff def do_common_stuff @foo = common_foo @bar = do_something_with @foo end

Ese es un enfoque totalmente legítimo. Pero si @foo cambia de controlador a controlador ... bueno, tienes algunas opciones más.

Puede separar los filtros anteriores en dos mitades y personalizar uno por controlador.

# application_controller: before_filter :get_foo, :do_something_common def do_something_common @bar = do_something_with @foo end # baz_controller: def get_foo @foo = pull_from_mouth end #baf_controller: def get_foo @foo = pull_from_ear end

Pero ya sabes, si es un caso simple que no necesita acceso a la base de datos o acceso a la red o algo así ... que tu caso no ... no se suicide. Y no te preocupes. Tirarlo en un ayudante. Para eso están, para ayudar. Básicamente, simplemente está reorganizando algunos datos de vista en una forma un poco más fácil de usar de todos modos. Un ayudante es mi voto. Y simplemente puedes nombrarlo next_url . :)

¿Cómo debería uno tener varias acciones de controlador diferentes establecer una variable de instancia común para uso en plantillas pero después de que se ejecuta la acción .

En otras palabras, quiero que esto funcione en mi controlador de aplicaciones.

class ApplicationController < ActionController::Base after_filter :set_something_common def set_something_common # All controllers'' actions have queried the DB and set @foo for me... @bar = some_calculation_on(@foo) # ... and all templates expect @bar to bet set. end end

Esto no funciona porque after_filter ejecuta después de la representación. Multa. Pero, ¿cuál es el patrón correcto?

Nuevamente, es importante que set_something_common ejecute después de la acción porque esas acciones hacen cosas específicas de cada caso; pero todos ellos establecen @foo .

Ninguna de mis ideas parece ideal:

  • Llame a set_something_common() hacia la parte inferior de cada acción que lo necesite.
  • Refactorice el código específico de caso de todos los controladores en case_specific_code() y obligue a que se ejecuten en orden:

    before_filter :case_specific_code, :set_something_common

  • Subclase application_controller y redefine el método de index .

¿Alguna idea? Gracias.

Edit: la respuesta de Matthew me impulsó a aclarar:

El índice de varios controladores () hace paginación, y cada uno toma los parámetros @offset y @limit (a través de un before_filter global) para ver los segmentos de datos. Genial. Ahora quiero un método común para calcular una URL RESTful para el enlace "siguiente porción". Me animaron a ver que url_for() genera una URL que regresa al mismo recurso, así que intenté:

def set_something_common # really called set_next_url, truth be told @next_url = url_for(:offset => @offset + @limit, :limit => @limit) end

Trataré de parchear el parche Fixnum, así que puedo hacer algo como @offset.next_url_for(self, @limit) desde la plantilla, pero no estoy seguro de si funcionará. Ahora que lo pienso, si voy a modificar las plantillas, entonces también puedo configurar un asistente de aplicación. Todavía no estoy seguro de cuál es la mejor solución.

Actualización: La respuesta aceptada es "usar un ayudante".

Gracias por las actualizaciones de todos. Aprendí mi lección de que los ayudantes, como las variables globales, están ahí por una razón y no deben ser evitados cuando son claramente beneficiosos y sucintos.


Tendría un método en @foo que devuelve una barra, de esa manera puedes usar @foo.bar en tus vistas.

<% @bar = @foo.bar %> # si realmente no quieres cambiar tus puntos de vista, pero no escuchaste esto de mí :)


Use <%= do_some_calculations(@foo) %> dentro de sus plantillas. Ese es el camino recto.