2011-02-11 703 views
5

Tengo un escenario en el que me gustaría tener el nombre de la vista que se renderizará mientras estoy en el archivo de diseño. Puedo encontrar soluciones para encontrar qué diseño envolverá la vista actual desde la vista, pero no al revés. ¿Cómo puedo encontrar qué vista está renderizando?Rails 3, encuentra la vista actual en el diseño

Respuesta

6

En Rails 3.0.3, yo era capaz de ver el nombre de el controlador y la acción utilizando controller_name y action_name. Pero esos no están documentados públicamente (al menos el nombre de la acción) por lo que no dependería de ello a largo plazo.

Podría ser mejor que renderizar la plantilla de parche mono. En un inicializador:

module ActionView::Rendering 
    alias_method :_render_template_original, :_render_template 
    def _render_template(template, layout = nil, options = {}) 
    @last_template = template 
    _render_template_original(template, layout, options) 
    end 
end 

Luego use @last_template en su diseño.

+0

Esto funcionó muy bien para mí. Para agregar un poco más de detalle, en Rails 3 lo agregué a un nuevo archivo config/initializers/custom_renderer.rb, y luego en la vista pude acceder a @ last_template.variable_name para obtener, por ejemplo, "new" –

+3

' ActionView :: Rendering' ya no existe en Rails 3.1. – Behrang

0

Me gusta el siguiente enfoque, ya que puede reducir un poco el tamaño del código en muchos casos. Incluir esto en su application_controller.rb:

before_filter :instantiate_controller_and_action_names 
    caches_action :instantiate_controller_and_action_names 

    def instantiate_controller_and_action_names 
    @current_action = action_name 
    @current_controller = controller_name 
    end 

Entonces, si sus puntos de vista corresponden a una acción, que acaba de hacer:

dosomething if @current_action == 'new' 
+0

Esto no acaba de resolver el problema que tengo. Necesito el nombre de la vista, y no siempre es lo mismo que la acción que se llama. –

+0

Simplemente agregue una acción en blanco, por ejemplo, defina el final. – jschorr

5

La siguiente solución funciona en Rails 3.1. Coloque este código en un inicializador. (La respuesta de los carriles 3.0.3 ya no funciona en Rails 3.1)

Esto habilita una variable @active_template para cada controlador. Esta es una instancia de una clase ActionViewTemplate.

El método active_template_virtual_path método devuelve la plantilla como el nombre de la siguiente forma "controlador/acción"


    class ActionController::Base 
     attr_accessor :active_template 

     def active_template_virtual_path 
     self.active_template.virtual_path if self.active_template 
     end 
    end 

    class ActionView::TemplateRenderer 

     alias_method :_render_template_original, :render_template 

     def render_template(template, layout_name = nil, locals = {}) 

     @view.controller.active_template = template if @view.controller 
     result = _render_template_original(template, layout_name, locals) 
     @view.controller.active_template = nil if @view.controller 
     return result 

     end 
    end 
+1

Esto funciona para mí con Rails 3.1.3. Aunque acorté un poco la solución: '@ view.assign (: active_template => template)' dentro de 'render_template', entonces puedes eliminar un montón del código adicional y acceder a la plantilla dentro de una vista como' @ active_template'. – David

+0

Descubrí que esto daba problemas a la joya 'exception_notification'. Para arreglar esto hice [estos cambios] (http://pastebin.com/raw.php?i=sd8f01mp). –

+0

Tuve un problema con los diseños anidados (http://guides.rubyonrails.org/layouts_and_rendering.html#using-nested-layouts). El active_template se estableció en mi diseño más alto en lugar de la vista desde el controlador. Para corregir, agregué una condición adicional en el archivo de assignment: '@view.controller.active_template = template if @ view.controller && @ view.controller.active_template.nil? ' –

Cuestiones relacionadas