La Coctelera

Tres de mis helpers para Ruby on Rails

16 mar 07

Un par de helpers para tener las vistas más limpias

A veces, al trabajar con layouts, queremos que determinadas partes de nuestras vistas dependan de si estamos (o no) en una acción o controlador determinados.

Uno de los inconvenientes de este tipo de condiciones (para mi gusto) es luego ver mucho código como este:

 <% if params[:action] != 'index' %>
   [...]
 <% end %>
 <% if params[:action] == 'show' or params[:action] == 'edit' %>
   [...]
 <% end %>
 

Para mi gusto ese tipo de condiciones son demasiado ruidosas para lo que hacen, así que tengo dos helpers: in_action? e in_controller?. Los argumentos son los mismos para ambas, y funcionarían así:

 <% if in_action? :except => 'index' %>
   [...]
 <% end %>
 <% if  in_action? :only => ['show', 'edit'] %>
   [...]
 <% end %>
 

A mí me gusta más, si a ti también, aquí viene el código de los helpers ^_^

   def check_in(element, list)
     raise ArgumentError, "Wrong parameter, #{list} is not a Hash" unless list.class == Hash
     if list[:only]
       list[:only]   = [list[:only]].flatten
       return (list[:only].include?(element))
     end
     
     if list[:except]
       list[:except] = [list[:except]].flatten 
       return (not list[:except].include?(element))
     end
     raise ArgumentError, "Required :only or :except"
   end
 
   def in_action?(actions={})
     check_in(params[:action],actions)
   end
 
   def in_controller?(controllers={})
     check_in(params[:controller],controllers)
   end
 

Si te prefieres, en vez de utilizar :only y :except, tener: in_action?, not_in_action?, in_controller? y not_in_controller?. Cambiar el código de antes debería ser trivial ;)

Un tercer helper: tab_link_to

A veces queremos usar menús de "tabs" (pestañas) en los que todos los enlaces tienen un estilo menos el de la página en la que nos encontramos que tiene un estilo distinto. Aquí en la coctelera, sin ir más lejos, tenemos los siguientes tabs:

Para evitarme más condiciones de las necesarias en las vistas hice el helper tab_link_to que, apoyándose en in_action? e in_controller?, añade class="selected" al enlace en el que nos encontramos.

   def tab_link_to(name, options = {}, html_options = nil, *parameters_for_method_reference)
     options[:controller] ||= params[:controller]
     options[:controller]   = options[:controller].to_s
     options[:action] = options[:action].to_s
     raise ArgumentError, "Action not specified" unless options[:action]
     
     html_options ||= {}
     html_options[:class] ||= ""
     if in_action?(:only => options[:action]) and in_controller?(:only => options[:controller])
       html_options[:class] = "#{html_options[:class]} selected".strip
     end
     
     return(link_to name, options, html_options, *parameters_for_method_reference)
   end
 

Los parámetros del helper son exactamente los mismos que los de link_to, pero hay que especificar siempre la acción a la que apunta el enlace con :action. Si no especificamos controlador se supondrá que es el mismo que en la petición actual.

2 comentarios

2 comentarios

  1. 17 mar 2007 | 12:48 PM # Fernando Blat Peris dice:

    Bueno, para comparar varias acciones siempre puedes utilizar la expresión regular:

    params[:action] =~ /action1|action2/

  2. 17 mar 2007 | 05:28 PM # Ernesto Jiménez dice:

    Esa expresión también reconocería acciones como: action10, action20, etc... La expresión regular puede no llegar a ser tan trivial. Además, y pese a que me encantan las expresiones regulares, no me parece correcto dejarlas en las vistas para sufrimiento del diseñador :)

Escriba un comentario: