2011-02-02 20 views
5

Estoy tratando de aprender los raíles desde cero experiencia de programación y tengo una aplicación que estoy tratando de hacer. Con mucha ayuda de las personas aquí, tengo una página de índice de lugares que son filtrables por qué área pertenecen a través de un menú desplegable. Me gustaría poder tener el mismo efecto pero usando casillas de verificación y también poder seleccionar áreas múltiples para agregar al filtro. Esto es lo que tengo hasta ahora:Uso de casillas de verificación para filtrar registros

Modelo:

class Venue < ActiveRecord::Base 
    belongs_to :user 
    has_many :reviews 
    belongs_to :area 

    scope :north, where(:area_id => "2") 
    scope :west, where(:area_id => "3") 
    scope :south, where(:area_id => "4") 
end 

controlador:

def index 
    if (params[:area] && Area.all.collect(&:name).include?(params[:area][:name])) 
    @venues = Venue.send(params[:area][:name].downcase) 
    else 
    @venues = Venue.all 
    end 
end 

Lugares index.html.erb:

<div class="filter_options_container"> 

    <form class="filter_form", method="get"> 
    <%= select("area", "name", Area.all.collect(&:name), {:prompt => 'All Areas'}) %><br> 
    <input type="submit" value="Filter" /> 
    </form> 

    <br><br> 

    <form class="filter_form", method="get"> 
    <% Area.find(:all).each do |a| %> 
     <%= check_box_tag("area", "name") %> 
     <%= a.name %> 
    <% end %> 
    <input type="submit" value="Filter" /> 
    </form> 
</div> 

<div class="venue_partials_container"> 
    <%= render :partial => 'venue', :collection => @venues %> 
    <div class="clearall"></div> 
    <%= link_to 'add a new venue', new_venue_path, :class => "add_new_venue_button" %> 
</div> 

la primera forma (los menús desplegables) en filter_options_container funciona bien pero las casillas de verificación (la segunda forma) están devolviendo "no se puede convertir Symbol into Integer "¿Qué estoy perdiendo/haciendo mal?

Gracias por cualquier ayuda.

Respuesta

8

No sé exactamente lo que está causando su error, pero te puedo decir que el ayudante no está funcionando como se espera que a. De the documentation, se define así:

check_box_tag(name, value = "1", checked = false, options = {}) 

Así que llamar repetidamente check_box_tag("area", "name") sólo le dará varias veces. Tenga en cuenta que el atributo "valor" (que es el valor que se envía a su servidor cuando se envía ese formulario) siempre es "nombre", ¡no lo que usted quiere!

su lugar, tratar las siguientes:

<% Area.all.each do |a| %> 
    <%= check_box_tag("areas[]", a.id) %> 
    <%=h a.name %> 
<% end %> 

Las cosas que he cambiado:

  1. Solía ​​Area.all en lugar de Area.find(:all) - Lo hice por razones cosméticas, pero la respuesta de DanneManne dice que es obsoleta en Rails 3 (no lo sé, todavía estoy en 2.3.8).
  2. Utilicé el ID del área en lugar de su nombre en el campo de valor; siempre es bueno buscar cosas por ID si puede: los ID son enteros y se comparan más rápido que las cadenas, y siempre habrá un índice en la columna de id. en su base de datos para búsquedas extra rápidas.
  3. Y por último, pero manera más importante Lancé [] después del nombre de la entrada. Esto permite que Rails recopile todos los valores enviados con este nombre en una matriz, en lugar de simplemente tomar la última.Vea a continuación:

Lanzar la URL ...

/whatever?a=3&a=17&a=12 

... en una aplicación Rails te da el hash params ...

{:a => 12} 

... pero la URL ...

/whatever?a[]=3&a[]=17&a[]=12 

... le da lo que quiere:

{:a => [3, 17, 12]} 

Y si tiene una matriz de todos los area_ids que le interesa, se pueden obtener todos los lugares que se encuentran en cualquier de esas áreas en una sola línea (no es gran Rails?) :

filtered_venues = Venue.all(:conditions => {:area_id => params[:areas]}) 

Sólo asegúrese de que tiene una matriz válida de id de zona antes de llamar a que el buscador - si no lo hace, su condiciones de hash evaluará a {: area_id => nil}, y Rails'll encontrarte todos los lugares que no tienen un area_id - probablemente ninguno, y definitivamente no es lo que quieres.

Espero que esto ayude!

+0

¡Muchas gracias por la brillante respuesta de su funcionamiento! – Dave

+0

@Dave Glad Yo podría ayudar! –

0

En su llamada a Area.find proporciona el argumento: all. Esta sintaxis está obsoleta en Rails 3, que supongo que está utilizando. Todos los usos previos de find (: all, ...) o find (: first, ...) etc. ya no se pueden usar. En su lugar, debería usarlo como usted en el primer formulario: Area.all (...)

Como nota al margen, también parece que los argumentos check_box_tag podrían estar equivocados. Supongo que deberías enviar un nombre en lugar de un "nombre".

Aquí es una forma modificada que creo que funciona:

<form class="filter_form", method="get"> 
    <% Area.all.each do |a| %> 
    <%= check_box_tag("area", a.name) %> 
    <%= a.name %> 
    <% end %> 
    <input type="submit" value="Filter" /> 
</form> 
Cuestiones relacionadas