Forum: Rails-ES problemas con consultas a BD

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Jose P. (Guest)
on 2007-07-26 02:44
hola a todos, no habia tenido la necesidad de escribir por ayuda pero
nuevamente estoy teniendo problemas con una aplicacion que estoy
realizando
Mi problema es el siguiente:
he tratado de crear un pequeño formulario donde pueda capturar un campo
llamado programa, y crear dos select uno llamado periodo y otro año.
lo que hace el formulario es generar una busqueda teniendo en cuenta
estos tres parametros. El formulario (que ha cambiado de forma mas de
mil veces) es:

<% form_tag ({:action => 'mostrar'}, {:class=>'matriculas'})do %>
<p><label for="programa">Programa</label><br/>
<%= text_field_tag "programa" %></p>
<label for="periodo">Periodo</label>
<%= select_tag( 'periodo',options_for_select([1,2]))%>
<label for="ano">A&ntilde;o:</label>
<%= select_tag(
'ano',options_for_select([2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012]))
%>
<%= submit_tag "Buscar"%>
 <%-end  %>

los dos select_tag que estan alli fueron una idea que tuve que
afortunadamente funciono para la vista pero al parecer no envia los
parametros al metodo del controller. Lo que en realidad quiero es que la
consulta me devuelva solo unas cuantas columns de la tabla . para ello
estaba utilizando find_by_sql de esta forma:
def mostrar
    @matriculas=Matricula.find_by_sql["select
codigo_estudiante,nombre_estudiante,programa,nivel from matriculas where
programa=?, periodo=?, ano=?,programa,periodo,ano"]
      end

el error que arroja el explorador es el siguiente:

ArgumentError in MatriculasController#mostrar
wrong number of arguments (0 for 1)
RAILS_ROOT: ./script/../config/..

Request
Parameters: {"programa"=>"sistemas", "commit"=>"Buscar", "ano"=>"2007",
"periodo"=>"1"}

por favor necesito ayuda
agradeciendo de antemano: Jose
Luis V. (Guest)
on 2007-07-26 10:36
(Received via mailing list)
Varias cosas:

- <%=
select_tag('ano',options_for_select([2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012]))%>
lo podrías sustituir por
<%= select_tag('ano',options_for_select(2001..2012))%>, que queda más
limpio
- Para la consulta que quieres, te iría mejor:
@matriculas=Matricula.find(
:all, :select =>
['codigo_estudiante','nombre_estudiante','programa','nivel'],
:conditions
=>['programa=?, periodo=?,
ano=?',params[:programa],params[:periodo],params[:ano]])

- El error ese parece que te dice que no le estás enviando argumentos al
método  y necesita uno, pero por lo que veo en la declaración (def
mostrar),
el método no requiere parámetros. Puede que te esté fallando por el
find_by_sql que no parece muy bien construido.

Prueba lo que te he dicho a ver si va.
Jose P. (Guest)
on 2007-07-26 23:28
Saludos Luis:
Bueno, el motivo del mensaje es el siguiente:
La ayuda que me diste en la parte del formulario funciono muy bien. en
realidad estaba con dudas con respecto a lo que habia hecho y no me
parecio lo mas estetico pero si lo mas practico.
En cuanto a la consulta en el controller me aparece un error:
MySQL::Error#21000 "Operand should contain 1 column(s)"
Lo investigue y resulta  que cuando se hace
Matricula.find(:all,:select[xxxxxxx] se esta incurriendo en esto SELECT
(SELECT column1, column2 FROM t2) FROM t1; (traducido a sql)
Habiendo encontrado esto borre la parte del :all y lo deje solo con el
:select pero ahora me arroja el siguiente error

ActiveRecord::RecordNotFound in
MatriculasController#mostrar
Couldn't find Matricula without an ID
c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/base.rb:1012:in
`find_from_ids'
c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/base.rb:419:in
`find'
#{RAILS_ROOT}/app/controllers/matriculas_controller.rb:68:in `mostrar'

no se por que me pide ahora los id de la tabla matriculas
Agradeciendo de antemano la ayuda que me puedas brindar me despido.
Gracias
Jose
Luis V. (Guest)
on 2007-07-27 10:29
(Received via mailing list)
Es que si no le pones el :all, intentará buscar sólo un registro que
tenga
como id el primer parámetro. Si no lo encuentra, salta una excepción.

El problema es que te dije mal los parámetros del :select. Se le pasa
una
cadena, no un array, así que te funcionaría así:

@matriculas=Matricula.find( :all, :select =>
"codigo_estudiante,nombre_estudiante,programa,nivel", :conditions
=>['programa=?, periodo=?,
ano=?',params[:programa],params[:periodo],params[:ano]])

Chequea la sintaxis, que ha sido un copypaste un poco cutre
Jose P. (Guest)
on 2007-07-27 22:50
Saludos Luis
sigue saliendo el mismo error a pesar de que lo corregi como me enviaste
el error es:
ActiveRecord::StatementInvalid in
MatriculasController#buscar_por_programa
Mysql::Error: #21000Operand should contain 1 column(s): SELECT
codigo_estudiante,nombre_estudiante,programa,nivel FROM matriculas WHERE
(programa='sistemas', periodo='1',ano='2007')
el metodo que ahora lo llamo buscar_por_programa es:
def buscar_por_programa
    @matriculas=Matricula.find( :all, :select
=>"codigo_estudiante,nombre_estudiante,programa,nivel",
:conditions=>['programa=?,
periodo=?,ano=?',params[:programa],params[:periodo],params[:ano]])
 end
Esta tal cual como me aconsejaste pero sigue saliendo ese error de sql.
Ya lo he modificado de muchas formas para ver si tenia suerte pero nada.
Creo que el error puede estar en la parte de params[:programa],
params[periodo]..... puesto que hice una prueba dejando solo un
parametro y salia pero apenas intentaba ponerle otro salia el error, no
hay otra forma de declarar los parametros en este tipo de metodos?

Ademas de esto queria hecerte otra pregunta (disculpa la preguntadera y
la ignorancia)
En la vista que me mostraba la consulta antes de seleccionar solo
algunas de las columnas me mostraba todas con este pedazo de codigo:

<% for matriculas in @matriculas %>
  <tr bgcolor="#FFFFFF">
  <% for column in Matricula.content_columns %>
    <td><%=h matriculas.send(column.name) %></td>
  <% end %>
Como puedo hacer para que solo muestre las columnas que he seleccionado?
Te agradesco mucho tu ayuda y tu paciencia Muchas gracias en verdad, por
todo
Jose
javier ramirez (Guest)
on 2007-07-27 23:24
(Received via mailing list)
Hola,

Si miras la sentencia SQL del log verás que el WHERE es incorrecto
> WHERE
> (programa='sistemas', periodo='1',ano='2007')
>
no puedes poner en sql una condición con ','. Los operadores (binarios)
válidos en sql son AND y OR (y between, pero eso es otra historia)

el caso es que tu claúsula conditions está mal. Donde tienes:
> :conditions=>['programa=?, periodo=?,ano=?', 
params[:programa],params[:periodo],params[:ano]])
>
deberías tener

:conditions=>['programa=? AND periodo=? AND ano=?',


Con respecto a la forma de recorrer las columnas de tu query en un caso
en el que usas :select podrías directamente usar el método attributes de
cada item que te devuelva la consulta.

No estoy seguro de que sea la mejor opción por temas de legilbilidad
porque estás metiendo un nivel de metaprogramación probablemente
innecesario (a no ser que realmente estés haciendo una función de
librería). Date cuenta de que con tu método estás metiendo un bucle para
ahorrarte escribir el nombre de cuatro campos. Pero funcionar funciona.

saludos,

javier ramírez
Luis V. (Guest)
on 2007-07-27 23:29
(Received via mailing list)
Uy, no sé si te dije mal. Lo que va en conditions es lo que iría en el
where, por lo que hay que separar las cosas con and. Así:
:conditions=>['programa=? and
periodo=? and ano=?',params[:programa],params[:periodo],params[:ano]]

Así ya te debería funcionar.

En cuanto a la segunda pregunta, lo que hace ese trozo de código es
iterar
sobre cada fila y dentro de cada fila iterar sobre cada columna del
objeto
Matricula. Para decirle tú las que quieres 2 opciones. No iterar y hacer
para cada fila de las que quieres algo así:

<% for matriculas in @matriculas %>
 <tr bgcolor="#FFFFFF">
   <td><%=h matriculas.send(codigo_estudiante) <http://column.name/>
%></td>
   <td><%=h matriculas.send(nombre_estudiante) <http://column.name/>
%></td>
......
 <% end %>


o aprovecharte del iterador y preguntar si el nombre de la columna es
alguno
de los que quieres. Así:

<% for matriculas in @matriculas %>
 <tr bgcolor="#FFFFFF">
 <% for column in Matricula.content_columns %>
   <%if
['codigo_estudiante','nombre_estudiante','programa','nivel'].include?column.name

   <td><%=h matriculas.send(column.name) %></td>
   <%end%>
 <% end %>
Jose P. (Guest)
on 2007-07-28 01:45
Muchas gracias por la ayuda
En realidad no tuve como ver lo de la sentencia, puesto que pense que en
rails la cuestion era asi, como en la sintaxis del mismo se maneja mucho
lo de las comas, y ademas como les digo solo soy un novato en esto,
llevo como un mes aprendiendo, aunque pensandolo bien debi haber puesto
mas de mi en eso .
Estoy muy agradecido por su ayuda y Javier gracias por responder solo
habia tenido la oportunidad de contar con la ayuda de Luis y Luis como
siempre hermano muchas gracias.
Jose
Jose P. (Guest)
on 2007-07-30 06:59
Saludos a todos
Me dirijo nuevamente a ustedes pidiendo consejo con respecto a lo
siguiente:
se que este tema lo han machacado y le han sacado el jugo en este foro
pero aun tengo dudas al respecto: lo del plugin  Acts As Authenticated.
Se que es una forma facil de autenticacion de usuarios, pero aun no he
sabido como restringir la entrada de usuarios.
Por ejemplo, tengo varios tipos de usuarios, coordinadores,
administrativos y profesores. Lo que quiero hacer es que cada uno de
ellos tenga permiso para acceder solo a ciertas tareas o paginas. He
leido al respecto y ya instale el plugin, lo he probado pero no he
podido restringir el acceso como yo quiero.
Tengo que modificar algo en la base de datos o agregar alguna tabla
donde se encuentren los perfiles, que debo hacer?.
Se que hay otro tipo de plugins que son complemento de este pero si no
se manejar muy bien este ahora menos otro.
Les agradeceria que me guiaran al respecto.
Muchas gracias
Jose
This topic is locked and can not be replied to.