Forms y Params

Soy nuevo en esto y estoy un poco desesperado por no encontrar la
solución a un error ‘You have a nil object when you didn’t expect it!’.
Agradecería que alguno de vosotros me apuntara la solución.

Por un lado tengo un formulario en ‘list.rhtml’:

Artista:

Por el otro quiero recoger la variable en ‘nm_controller.rb’:

def resultado
page = (params[:page] ||= 1).to_i
fichas_per_page = 30
offset = (page - 1) * fichas_per_page

condiciones=[]
artista1 = params[:art]
condiciones << “Artista like (’%#{artista1}%’)”

@fichas = Ficha.find (:all, :conditions => condiciones.join(" and "),
:order => (‘Artista, Album’))
@ficha_pages = Paginator.new(self, @fichas.length, fichas_per_page,
page)
@fichas = @fichas[offset…(offset + fichas_per_page - 1)]
end

Me ‘pagina’ la primera página pero la siguiente me da el error apuntado
anteriormente. Sé que es un error de puesta a punto de la ‘Array
params[:art]’, ya que si sustituyo la variable ‘artista1’ por un valor
concreto todo va estupendamente. No sé cómo solucionarlo, dada mi poca
experiencia en rails. Espero vuestras sugerencias.

Gracias de antemano.

Mirando así por encima parece que cuando pasas a la siguiente página, el
input “art” no tiene valor, por lo que cuando haces artista1 =
params[:art],
artista1 se queda vacío, y luego al intentar construir la cadena de
condiciones, peta.

Solución:

  • Pon Artista:
    en la
    vista
  • Pon @artista1 = params[:art] en el controlador ----> Añadiendo una @
    para
    que lo pase a la vista como parámetro
  • Si sólo tienes una condición en tu controlador, no hace falta que
    pongas
    lo de condiciones.join(" and ")
  • Para crear las condiciones, pon: condiciones = [“Artista like
    ?”,@artista1] if @artista1, así te evitas que te metan sql injection y
    te
    crea sólo el array condiciones si @artista1 no es nulo
  • Y luego: @fichas = Ficha.find (:all, :conditions =>
    condiciones,:order =>
    (‘Artista, Album’)) —> Así te crea la query y si condiciones es nulo
    no
    se pasará ningún parámetro

Eso seguramente es porque la primera vez le haces un post con el botón
submit, por lo que se te envían los inputs.
Pero al darle a los numeritos de la paginación, se hace un GET, por lo
que
tu método sólo recibe los parámetros que van en la url.

Lo suyo es que al construir los links de la paginación le pases en la
url
que se forma un parámetro art que contenga la búsqueda

Gracias Luís por tus sugerencias. He seguido al pie de la letra las
indicaciones que me apuntas y lo que ocurre es que al seleccionar la
siguiente página se pierde la busqueda y vuelven a aparecer todos los
registros :frowning:

Te indico cómo queda el código hasta ahora:

En Vista:
form action=“resultado” method=“post”>
Artista:

En Controlador:

def resultado
page = (params[:page] ||= 1).to_i
fichas_per_page = 30
offset = (page - 1) * fichas_per_page

@artista1 = params[:art]
condiciones = [“Artista like ?”,@artista1] if @artista1
@fichas = Ficha.find (:all, :conditions => condiciones, :order =>
(‘Artista, Album’))

@ficha_pages = Paginator.new(self, @fichas.length, fichas_per_page,
page)
@fichas = @fichas[offset…(offset + fichas_per_page - 1)]

end

Gracias por tu atención,

Diego

A través de las indicaciones de Luís y con la ayuda de
http://tanreisoftware.com/blog/?p=5 ( en inglés) he podido, por fin,
solucionar el problema que me traía de cabeza.
Resumiendo y para aquél que le pudiera interesar, la cosa quedaría así.

-En vista ‘Form’:

Artista: Álbum:

-En Controlador:

def resultado
@per_page=30
@artista1 = params[:art]
condiciones = [“Artista like ?”,@artista1] if @artista1
@fichas = Ficha.find (:all, :conditions => condiciones, :order =>
(‘Artista, Album’))
@ficha_pages, @fichas = paginate_collection @fichas, :per_page =>
@per_page, :page => params[:page]
end

def paginate_collection2(coll, options = {})

Grab params and fix em up

per = options[:per_page].to_i
page = (params[:page] || 1).to_i
offset = (page - 1) * per

Create a Paginator based on the collection data

pages = Paginator.new self, coll.size, per, page

Grab the sub-set of the collection

paged = coll[offset…(offset + per - 1)]
return [pages, paged]
end

-En vista ‘Resultado’ (paginar):


<%= pagination_links(@ficha_pages, {:params => {:art => @artista1}})
%>

Gracias por vuestra atención,

Diego