2010/2/23 Matias Pablo Brutti <[email protected]>:
> 2010/2/22 Nicolás Sanguinetti <[email protected]>:
>> Y, la solución obvia—y correcta—es la que vos terminaste haciendo.
>> Migrá la base de datos y hacé la columna not null y con default 0.
>>
>> def self.up
>> change_column :movements, :debit, :integer, :null => false, :default => 0
>> change_column :movements, :credit, :integer, :null => false, :default => 0
>> end
>>
>> Ahí pasa a funcionar solo :)
>>
>> Si no, la siguiente mejor solución (si no podés tocar la base de
>> datos, por ejemplo), es decirle a rails que el campo ese siempre sea
>> un integer, sin importar el valor en la base de datos:
>>
>> class ClientMovement < ActiveRecord::Base
>> def debit
>> read_attribute(:debit).to_i
>> end
>> end
>>
>> Y seguiría funcionando transparentemente -- movements.sum(&:debit)
>> devolvería lo que querés sin necesidad de hacer nada en la vista.
>>
>> Pero ta, si el cambio pasa en la base, mucho mejor.
>>
>> Hacer el casteo o filtrado en las vistas cada vez que necesitás el
>> valor es una grosería :)
>
> Las grocerias de algunos son requisitos de otros. :)
> Encodear es un MUST, mas cuando estas haciendo aplicaciones que no
> siempre estas seguro de donde viene el input y si fue correctamente
> sanitizado o no.
> Ademas, hay veces donde se necesita un tipo de sanitizacion en un
> lado y otro en otro lado, todo depende en donde estes renderizando la
> informacion, por ende:
Y… cómo decía, si por algún motivo no podés hacerlo en la base de
datos, entonces hacelo en el modelo. Ya tenés una forma perfectamente
"natural" de hacerlo sobreescribiendo el attr_reader. O si el día de
mañana eso cambia querés cambiarlo en las N vistas que lo tocan en
lugar de en *el* lugar en el modelo?
Además de que para testearlo, preferís testear un método del modelo, o
un montón de vistas?
Las vistas tienen que ser lo más estúpidas posibles, con la menor
cantidad de código. Entre un modelo y un presenter (que en rails-speak
serían helpers, en general) deberías de tener toda la lógica para
trabajar los datos transparentemente.
Y *en el caso*, de que, por algun motivo, necesites que debit/credit
NO sean números en UN LUGAR, entonces los casteas a lo que necesitás
ahí. Pero si esa columna es un integer, entonces lo correcto es que
sea en la base, y si no podés, hacé el cambio en UN SOLO LUGAR.
La seguridad es, más y más, algo de lo que para las tareas mundanas
(como escapar el input), se encarga rails. Lo que no quiere decir que
no tengas que escribir código teniendo en cuenta una serie de cosas,
estoy totalmente de acuerdo contigo en que es re importante. Pero lo
que la seguridad no es, es una excusa para escribir mal código.
Y como todo, puede que en otros casos sea distinto, no hay una única
forma de hacer las cosas bien, pero EN ESTE CASO, en el ejemplo que el
OP puso, debit y credit son números, no trates de darle vueltas :)
> Yo diria que cada vez que no encodeas en el input o en el output
> MUEREN MIL GATITOS !!!!!!!!!!
> A vos te gustan los gatitos Nico ???
>
> Slds.
>
>>
>> Sobre el query en sí, ActiveRecord te da un API "relativamente"
>> elegante (según cómo se lo mire) para no tener que escribir SQL a
>> mano. En particular, lo que vos querés, es hacer JOIN con un par de
>> tablas y filtrar por una condición, y quedaría así:
>>
>> ClientMovement.all(:joins => [:inquiry, :client], :conditions => {
>> "clients.id" => params[:id] })
>>
>> Entre otras cosas, esto te evita el SQL injection que te mencionaron,
>> y es mucho más fácil de leer. (El valor de :joins asume que
>> ClientMovement tiene una asociación "belongs_to :client" y "belongs_to
>> :inquiry". En caso de que fueran has_many, lo que le pasás es el
>> nombre de la asociación, por lo que sería :joins => [:inquiries,
>> :clients])
>>
>> Y finalmente, habrás visto que los ejemplos de código los escribo en
>> inglés. Cada vez que alguien mezcla idiomas distintos en código, se
>> muere un gatito. Vos no querés que se mueran gatitos, verdad?
>>
>> POR FAVOR, ESCRIBAN EL CÓDIGO EN UN SÓLO IDIOMA.
>>
>> O hacen un interprete de ruby donde las palabras clave y constantes,
>> etc están en español (clase Arreglo < Objeto; fin), o escriben todo el
>> código en inglés. Pero es horriblemente molesto leer código en idiomas
>> mezclados.
>>
>> Saludos,
>> -foca
>>
>> PD: Mirá la documentación de ActiveRecord::Base#read_attribute (y ya
>> que estás, write_attribute) para entender cómo funciona la segunda
>> solución. Y la de ActiveRecord::Base.find para ver las opciones qué le
>> podés pasar, así no tenés que hacer find_by_sql.
>>
>>
>> 2010/2/22 Nestor Rodriguez <[email protected]>:
>>> Hola gente, como andan, aqui peleandome con el array, estoy tratando de
>>> hacer un sistema de cuentas corrientes y estoy con eso del DEBITO Y EL
>>> CREDITO, así que necesito mostrar el ESTADO DE CUENTAS de un cliente, por lo
>>> tanto en el CONTROLADOR escribo esto:
>>>
>>> @clientes_movimientos = ClienteMovimiento.find_by_sql("Select
>>> clientes_movimientos.* " +
>>> "from clientes_movimientos, solicitudes, clientes " +
>>> "where clientes_movimientos.solicitud_id = solicitudes.id
>>> and " +
>>> " solicitudes.cliente_id = clientes.id and " +
>>> " clientes.id = #{params[:id]}")
>>> AQUÍ NO ESTA EL PROBLEMA, el problema es que en el array que me genera,
>>> vienen dos campos, DEBITO y CREDITO, que quiero sumarlos (cada uno un su
>>> columna) para mostrar los totales algo así como:
>>>
>>> fec mov Concepto Debito Credito Fec
>>> vencimiento Num cuota Observacion
>>> 22/02/2010 Cuota 300,000 02/02/2010 1/4
>>> debito automatico
>>> 22/02/2010 Cuota 200,000 02/04/2010 2/4
>>> debito automatico
>>> 22/02/2010 Cuota 200,000 02/05/2010 3/4
>>> debito automatico
>>> 22/02/2010 Cuota 200,000 02/06/2010 4/4
>>> debito automatico
>>> TOTAL 1,000,000 0
>>>
>>> Lo que pasa es que el campo CREDITO, como no se le cargo nada tiene valores
>>> nulos, ahora bien mi pregunta es la siguiente:
>>> Como le digo a un bloque, que si es nulo el campo, lo tome como 0 (cero).
>>> Algo así como
>>>
>>> @clientes_movimientos.sum {|cm| ifnull(cm.debito,0)}
>>> @clientes_movimientos.sum {|cm| ifnull(cm.credito,0)}
>>>
>>> Obviamente la funcion ifnull no es de ruby que yo sepa. Pero cuando le
>>> coloco de la forma que aprendí es decir así:
>>> @clientes_movimientos.sum {|cm| cm.debito}
>>> @clientes_movimientos.sum {|cm| cm.credito}
>>>
>>> Me lanza un error ya que cm.credito es nulo y no lo puede sumar.
>>>
>>> Alguien sabe una función que transforme un valor nulo aquí en por ejemplo 0
>>> (cero).
>>>
>>> Desde ya gracias...
>>>
>>> Néstor R.
>>>
>>>
>>>
>>> _______________________________________________
>>> Ruby mailing list
>>> [email protected]
>>> http://lista.rubyargentina.com.ar/listinfo.cgi/ruby-rubyargentina.com.ar
>>>
>> _______________________________________________
>> Ruby mailing list
>> [email protected]
>> http://lista.rubyargentina.com.ar/listinfo.cgi/ruby-rubyargentina.com.ar
>>
>
>
>
> --
> --
> --<自由編碼人>--
> B.Sc. Matias Pablo Brutti
> Senior Security Consultant
> Email : [email protected]
> Site: http://www.freedomcoder.com.ar
> _______________________________________________
> Ruby mailing list
> [email protected]
> http://lista.rubyargentina.com.ar/listinfo.cgi/ruby-rubyargentina.com.ar
>
_______________________________________________
Ruby mailing list
[email protected]
http://lista.rubyargentina.com.ar/listinfo.cgi/ruby-rubyargentina.com.ar