Ruby Forum Rails-ES > Acceder a un parametro en el modelo con Rails

Posted by Manuel Pernalete (Guest)
on 02.05.2008 16:15
(Received via mailing list)
Buenos dias amigos de la lista RoR-Es

Yo se que en el controller para acceder a un parametro que se envia 
desde la
vista con un formulario es asi:
variable = params[:user][:login]

Ahora bien en el modelo (user.rb) tengo una funcion donde voy hacer unas
validaciones al campo login por lo que voy a usar funciones de cadena de
ruby como variable.length, entre otras....

Entonces el problema que tengo es que no sé como guardar en una variable 
el
campo login

Alguien me puede hechar una mano??

Muchas Gracias
Posted by Manuel Pernalete (Guest)
on 02.05.2008 17:20
(Received via mailing list)
OJO YO SE QUE PUEDO VALIDAR EL LENGTH DE UNA CADENA CON:

validates_length_of

ESO LO DESDE QUE COMENCE A PROGRAMAR BAJO RoR....
Necesito acceder al valor del parametro del campo de la tabla para
hacer unas validaciones especificas mediante un algoritmo un poco
complejo...


2008/5/3 Manuel Pernalete <mpernaletetorres@gmail.com>:
Posted by Manuel González Noriega (Guest)
on 02.05.2008 18:06
(Received via mailing list)
2008/5/2 Manuel Pernalete <mpernaletetorres@gmail.com>:
> OJO YO SE QUE PUEDO VALIDAR EL LENGTH DE UNA CADENA CON:
>
> validates_length_of
>
> ESO LO DESDE QUE COMENCE A PROGRAMAR BAJO RoR....
> Necesito acceder al valor del parametro del campo de la tabla para hacer
> unas validaciones especificas mediante un algoritmo un poco complejo...
>

¿Quieres decir acceder algo como recuperar el login del usuario con id 
1?

@user = User.find(1)
@user.login

?

Si se trata de eso, espero que te sirva, pero deberías considerar el
estudiar con detenimiento algunos tutoriales de iniciación a Rails y
ActiveRecord porque este mapeo es una de las características 
másbásicas del framework en lo referente al trabajo con base de datos.
Especialmente te vendría bien repasar alguno de los tutoriales de
iniciación del libro "Agile Web Development With Rails" o los
capítulos sobre AR de The Rails Way.

Si no se trata de eso lo que preguntabas, clarifícalo un poco.

--
Manuel, que
piensa que eres una excelente persona y medra en torno a
http://simplelogica.net y/o http://simplelogica.net/logicola/
Recuerda comer mucha fruta y verdura.
Posted by Manuel Pernalete (Guest)
on 02.05.2008 18:18
(Received via mailing list)
hola manuel gonzalez no se trata de eso...

las instrucciones que colocaste:
@user = User.find(1)
@user.login

se usan sin problemas en el controller pero si tu colocas esas 
instrucciones
en el modelo
te da el error de que el objeto es nulo (nil).

yo en el modelo tengo

class Suscripcion < ActiveRecord::Base
validates_presence_of :login, :if => :validar_login

def validar_login
variable = {Aqui no s{e como obtener el login del usuario}

He colocado
variable = :login
variable = @suscripcion.login
Pero ninguna me sirve
.
.
.
.
end

end



El día 3 de mayo de 2008 11:36, Manuel González Noriega <
manuel.gonzalez.noriega@gmail.com> escribió:
Posted by Omar Jimenez (Guest)
on 02.05.2008 18:55
(Received via mailing list)
probaste con solo login a si a secas ?

variable = login

segun recuerdo uso eso yo, en algunos modelos y va bien, me dices que 
tal va

Ing Omar S. Jimenez Becerra

El día 2/05/08, Manuel Pernalete <mpernaletetorres@gmail.com> escribió:
Posted by Ruben Davila (rdavila)
on 02.05.2008 19:17
(Received via mailing list)
Hola Manuel, ahora si se te entiende algo mejor, para hacer lo que 
necesitas
es suficiente con lo que te dice Omar, pero creo que tienes que saber 
como
funciona el tema, aqui alguna aclaracion:

self es como un puntero en Ruby que apunta a la instancia que tienes en 
un
momento momento determinado de esa clase, entonces podrias hacer lo
siguiente:

class User < ActiveRecord::Base
  def tu_metodo
    if self.login.blank?
      ....
    end
  end
end

self.login te devolvera el valor que tienes para el atributo login en 
una
determinada instancia de la clase User(osea un objeto), por ejemplo si
tenemos lo siguiente:

@user = User.new(:login => 'foo@bar.com')

Entonces cuando llames a @user.tu_metodo tendras disponible el valor del
atributo login a traves de self.login en la definicion de tu clase, otra
cosa es importante es que esto tambien funciona:

class User < ActiveRecord::Base
  def tu_metodo
    if login.blank?
      ....
    end
  end
end

Aqui no usamos self, y lo que hace Ruby es verificar primero si login es 
una
variable local, si no existe esa variable entonces se fija si existe un
metodo con ese nombre lo cual si existe, esta manera de comprobar el 
valor
devuelto por un metodo de una clase no es algo recomendable ya que 
conforme
tu codigo vaya creciendo te crearas confusiones tu mismo ya que no 
sabras si
estas llamando a una variable local o a un metodo, por lo que se 
aconseja
siempre usar la notación self.atributo cada vez que quieras invocar a un
metodo que es un getter.

Saludos.


El día 2 de mayo de 2008 11:47, Omar Jimenez <omar.omarseb@gmail.com>
escribió:
Posted by Manuel Pernalete (Guest)
on 03.05.2008 11:49
(Received via mailing list)
Gracias por la explicacion, tanto Omar como Ruben.
Les comento que si accedo al valor mediante: self.login entonces cree mi
metodo (validar_login) en el modelo que devuelve true o false si la 
sintaxis
del campo Login del usuario es correcta o no.
Pero tengo el problema que en validates_presence_of :login, :if =>
:validar_login? no me esta funcionando porque me guarda el registro y el
login que le estoy dando es incorrecto, es decir, no me da error antes 
de
incluir.

Entonces les comento a ustedes (Omar y Ruben) y a todos mis colegas de 
la
lista RoR-es que he encontrado otra solucion que me funciona 
perfectamente
pero necesito saber si es la solucion mas optima (a nivel de codigo) 
alli
les va.

En el controller (users_controller.rb) tengo lo siguiente:

def create
@loginvalido = User.validar_login(params[:user][:login])
@user = User.new(params[:user])
respond_to do |format|
if @user.save and @rifvalido
        flash[:notice] = 'Los datos han sido registrados
satisfactoriamente.'
        format.html { redirect_to(@user) }
        format.xml  { render :xml => @user, :status => :created, 
:location
=> @user }
      else
        @user.errors.add ('login','^El campo Login es Inválido.')
        format.html { render :action => "new" }
        format.xml  { render :xml => @user.errors, :status =>
:unprocessable_entity }
      end
end

Y en el modelo (user.rb) tengo lo siguiente:

class User < ActiveRecord::Base
......

def validar_login(L)
# aqui hago mi algoritmo de validacion de la
#sintaxis del login que me llega por parametro
......
......
end

ENTONCES QUE LES PARECE COLEGAS DE LA LISTA??? ES OPTIMA LA SOLUCION?? 
ES
MUCHO MEJOR??

ESPERO SUS OPINIONES AL RESPECTO....

MUCHAS GRACIAS!!!

El día 3 de mayo de 2008 12:46, Ruben. D. <ruben.grunge84@gmail.com>
escribió:
Posted by Claudio Perez gamayo (crossblaim)
on 03.05.2008 14:35
(Received via mailing list)
Pero que es lo que quieres validar?

te has leido la documentacion de ActiveRecord?

validates_presence_of :login
validates_format_of :login, :with => REGEXP
etc...

aqui todas las respuestas a tus dudas:

http://rails.rubyonrails.com/classes/ActiveRecord/Validations/ClassMethods.html

mira tambien #validate



El 04/05/2008, a las 5:12, Manuel Pernalete escribió:
Posted by Claudio Perez gamayo (crossblaim)
on 03.05.2008 14:45
(Received via mailing list)
No es optima, no es mejor, es mala.

Intenta no escribir todo en mayusculas.

On May 4, 2008, at 5:12, "Manuel Pernalete"
Posted by Omar Jimenez (Guest)
on 03.05.2008 16:53
(Received via mailing list)
Pero tengo el problema que en validates_presence_of :login, :if =>
:validar_login? no me esta funcionando porque me guarda el registro y el
login que le estoy dando es incorrecto, es decir, no me da error antes 
de
incluir.

mmm, pues ahi esta diciendo que valide la presencia de login, si el 
login es
valido, por tanto si no es valido ( validar_login? de false) no validas 
la
presencia de login, lo cual no creo que sea ni cercas de lo que 
necesitabas
pues seria algo asi como
if loginValido
  if login && login.length > 0
  #guarda registro
  else
   #no guardes
  end
else
  #guarda registro
end


o algo por el estilo, pero creo que esta muy lejos de lo que buscabas, 
en
cambio lo que propones me parece buena solucion, el validarlo


en el controlador donde se recibe y si todo esta bien guardarlo. lo 
unico
que me saco un poquito fue ese @rifvalido <-- que no vi de donde venia 
pero
supongo que tiene que ver con login valido o algo mas de tu logica =P, 
pero
suerte, a mi me parece bien la solucion de hecho tengo algo similar en
algunos de mis controladores.

Ing. Omar S. Jimenez Becerra
El día 3/05/08, Manuel Pernalete <mpernaletetorres@gmail.com> escribió:
> Gracias por la explicacion, tanto Omar como Ruben.
> Les comento que si accedo al valor mediante: self.login entonces cree mi
metodo (validar_login) en el modelo que devuelve true o false si la 
sintaxis
del campo Login del usuario es correcta o no.
>  Pero tengo el problema que en validates_presence_of :login, :if =>
:validar_login? no me esta funcionando porque me guarda el registro y el
login que le estoy dando es incorrecto, es decir, no me da error antes 
de
incluir.
>
> Entonces les comento a ustedes (Omar y Ruben) y a todos mis colegas de la
lista RoR-es que he encontrado otra solucion que me funciona 
perfectamente
pero necesito saber si es la solucion mas optima (a nivel de codigo) 
alli
les va.
>
> En el controller (users_controller.rb) tengo lo siguiente:
>
> def create
> @loginvalido = User.validar_login(params[:user][:login])
> @user = User.new(params[:user])
> respond_to do |format|
> if @user.save and @rifvalido
>          flash[:notice] = 'Los datos han sido registrados
satisfactoriamente.'
>         format.html { redirect_to(@user) }
>         format.xml  { render :xml => @user, :status => :created, :location
=> @user }
>        else
>         @user.errors.add ('login','^El campo Login es Inválido.')
>         format.html { render :action => "new" }
>         format.xml  { render :xml => @user.errors, :status =>
:unprocessable_entity }
> #sintaxis del login que me llega por parametro
>  ......
> ......
> end
>
> ENTONCES QUE LES PARECE COLEGAS DE LA LISTA??? ES OPTIMA LA SOLUCION?? ES
MUCHO MEJOR??
>
> ESPERO SUS OPINIONES AL RESPECTO....
>
> MUCHAS GRACIAS!!!
>
>
> El día 3 de mayo de 2008 12:46, Ruben. D. <ruben.grunge84@gmail.com>
escribió:
>
>
> > Hola Manuel, ahora si se te entiende algo mejor, para hacer lo que
necesitas es suficiente con lo que te dice Omar, pero creo que tienes 
que
saber como funciona el tema, aqui alguna aclaracion:
> >
> > self es como un puntero en Ruby que apunta a la instancia que tienes en
un momento momento determinado de esa clase, entonces podrias hacer lo
siguiente:
> >
> > class User < ActiveRecord::Base
> >   def tu_metodo
> >     if self.login.blank?
> >       ....
> >     end
> >   end
> > end
> >
> > self.login te devolvera el valor que tienes para el atributo login en
una determinada instancia de la clase User(osea un objeto), por ejemplo 
si
tenemos lo siguiente:
> >
> > @user = User.new(:login => 'foo@bar.com')
> >
> > Entonces cuando llames a @user.tu_metodo tendras disponible el valor del
atributo login a traves de self.login en la definicion de tu clase, otra
cosa es importante es que esto tambien funciona:
> >
> > class User < ActiveRecord::Base
> >    def tu_metodo
> >      if login.blank?
> >        ....
> >      end
> >    end
> >  end
> >
> > Aqui no usamos self, y lo que hace Ruby es verificar primero si login es
una variable local, si no existe esa variable entonces se fija si existe 
un
metodo con ese nombre lo cual si existe, esta manera de comprobar el 
valor
devuelto por un metodo de una clase no es algo recomendable ya que 
conforme
tu codigo vaya creciendo te crearas confusiones tu mismo ya que no 
sabras si
estas llamando a una variable local o a un metodo, por lo que se 
aconseja
siempre usar la notación self.atributo cada vez que quieras invocar a un
metodo que es un getter.
> >
> > Saludos.
> >
> >
> >
> > El día 2 de mayo de 2008 11:47, Omar Jimenez <omar.omarseb@gmail.com>
escribió:
> > > segun recuerdo uso eso yo, en algunos modelos y va bien, me dices que
tal va
> > >
> > > Ing Omar S. Jimenez Becerra
> > >
> > > El día 2/05/08, Manuel Pernalete <mpernaletetorres@gmail.com>
escribió:
> > >
> > >
> > > >  hola manuel gonzalez no se trata de eso...
> > > >
> > > > las instrucciones que colocaste:
> > > >  @user = User.find(1)
> > > >  @user.login
> > > >
> > > > se usan sin problemas en el controller pero si tu colocas esas
instrucciones en el modelo
> > > > He colocado
> > > >
> > > >
> > > >
> > > >
> > > > El día 3 de mayo de 2008 11:36, Manuel González Noriega <
manuel.gonzalez.noriega@gmail.com> escribió:
> > > >
> > > >
> > > > > 2008/5/2 Manuel Pernalete <mpernaletetorres@gmail.com>:
> > > > >
> > > > > > OJO YO SE QUE PUEDO VALIDAR EL LENGTH DE UNA CADENA CON:
> > > > >  >
> > > > >  > validates_length_of
> > > > >  >
> > > > >  > ESO LO DESDE QUE COMENCE A PROGRAMAR BAJO RoR....
> > > > >  > Necesito acceder al valor del parametro del campo de la tabla
para hacer
> > > > >  > unas validaciones especificas mediante un algoritmo un poco
complejo...
> > > > >  >
> > > > >
> > > > >  ¿Quieres decir acceder algo como recuperar el login del usuario
con id 1?
> > > > >
> > > > >  @user = User.find(1)
> > > > >  @user.login
> > > > >
> > > > >  ?
> > > > >
> > > > >  Si se trata de eso, espero que te sirva, pero deberías considerar
el
> > > > >  estudiar con detenimiento algunos tutoriales de iniciación a
Rails y
> > > > >  ActiveRecord porque este mapeo es una de las características más
> > > > >  básicas del framework en lo referente al trabajo con base de
datos.
Posted by Manuel Pernalete (Guest)
on 03.05.2008 17:33
(Received via mailing list)
no amigo ese @rifvalido fue un error de mio pero eso no esta en el
codigo....

y el algoritmo de validacion es algo complicado... se los explico a 
grandes
rasgos...

el login esta compuesto por 10 caracteres en total, el primero de ellos
tienen que ser las letras 'V', 'E', 'J', 'G' despues bien 9 caracteres 
del
0..9. en el algoritmo tomo cada uno de esos digitos y los multiplico por
multiplos de dos segun su posicion en la cadena, luego esos resultados 
de
los sumo y el total calculo el resto al dividirlo entre 11 ese numero 
que me
da debe ser igual al ultimo digito de la cadena Login. Si no lo es 
entonces
return false.

Entonces amigo Claudio le informo que me en mi proyecto uso todos los
validates pero en ese caso particular ninguno me sirve...

Ahora tengo un problema la primera vez que envio el formulario a guardar 
me
muestra el mensaje de error de que el 'Login es Inválido' pero cuando le 
doy
por segunda vez rails pareciera que no me llama al metodo y pasa sin
problemas y me guarda :S diosssssss ahora alli si no se que esta 
pasando...

si alguien tiene una idea para que me aclare el panorama por favor




El día 4 de mayo de 2008 10:23, Omar Jimenez <omar.omarseb@gmail.com>
escribió:
Posted by Omar Jimenez (Guest)
on 03.05.2008 17:46
(Received via mailing list)
un detalle entonces con @rifvalido quiziste decir @loginvalido ?

if @user.save and @rifvalido  <-- eso de ahi no deberia ser if 
@loginvalido
&& @user.save   <--- ( el loginvalido primero, pues de la otra forma, si 
el
login no es valido primero salvas y te regresa si se pudo salvar, 
despues
preguntarias si el login es valido.

y pudieras explicar un poco mas, lo que va mal que no te lo cache muy 
bien.

Ing. Omar S. Jimenez Becerra



El día 3/05/08, Manuel Pernalete <mpernaletetorres@gmail.com> escribió:
Posted by Manuel Pernalete (Guest)
on 03.05.2008 18:09
(Received via mailing list)
Vaya Omar tenias razon probe y coloque en el if lo que me dijiste, es 
decir,
cambie
if @user.save && @loginvalido por if @loginvalido && @user.save

y me funciono de verdad que no sabia que rails primero me grababa yo 
creia
que me evaluaba la instruccion @user.save && @loginvalido como un todo

jejeje gracias hermano buen dia

El día 4 de mayo de 2008 11:16, Omar Jimenez <omar.omarseb@gmail.com>
escribió:
Posted by Omar Jimenez (Guest)
on 03.05.2008 18:34
(Received via mailing list)
=P vaya no te apures que de esas luego a todos nos pasan

pero pues como dices evalua todo, va por partes del if teniendo

if @user.save && @loginvalido

primero va y ejecuta @user.save como ya no tienes ninguna validacion 
como
antes, pues todo va bien y graba, te regresa true
va a @loginvalido y ve que es false, entonces true && false pues da 
false
pero te llevas la sorpresa que si te grabo xD.

claro esta que podrias hacer las validaciones sin salvar nada mas, algo 
asi
como

if @user.valid? && @loginvalido

que segun tengo entendido @user.valid  ejecutaria todas las validaciones 
que
se pusieron en el modelo.

sale pues suerte que bueno que resolviste tu problema.

Ing. Omar S. Jimenez Becerra

El día 3/05/08, Manuel Pernalete <mpernaletetorres@gmail.com> escribió:
Posted by Claudio Perez gamayo (crossblaim)
on 03.05.2008 19:19
(Received via mailing list)
> Entonces amigo Claudio le informo que me en mi proyecto uso todos  
> los validates pero en ese caso particular ninguno me sirve...

Rails (ActiveRecord) te permite escribir tus propias validaciones a
medida, por muy complejas que estas sean.

Y ya te he dicho como se hace, define el metodo validate en tu modelo.

Insisto, leete la documentacion de ActiveRecord. Esta todo ahi.
Posted by Manuel Pernalete (Guest)
on 03.05.2008 19:52
(Received via mailing list)
Hola claudio seguí tu recomendacion y efectivamente creando un metodo
validate me funciona tambien. Ahora que es lo mas optimo para la 
aplicacion?
que el algoritmo personal de validacion lo haga en el modelo? o crear un
metodo en el controller y hacer una llamada a ese metodo alli mismo y 
hacer
la validacion?

Lo he hecho de las dos maneras y me funciona. Pero queda la gran 
pregunta?
cual es el codigo mas optimo?

El día 4 de mayo de 2008 12:48, Claudio Perez Gamayo 
<crossblaim@gmail.com>
escribió:
Posted by Francesc Esplugas (fesplugas)
on 03.05.2008 19:56
(Received via mailing list)
+1 a que esté dentro del modelo.
Posted by Claudio Perez gamayo (crossblaim)
on 03.05.2008 20:47
(Received via mailing list)
En el modelo, claro.

El 04/05/2008, a las 13:22, Manuel Pernalete escribió: