¿Problema con variable de clase?

Pues veréis, estoy refactorizando código y haciéndolo más legible y
bueno he hecho varios cambios, entre ellos uno que me está dando un
“leve” dolor de cabeza.

Veréis necesito controlar con un flag cuando se puede realizar varias
acciones (cambios, ventas, etc…), pues bien, en un principio lo
controlaba mediante un campo en una tabla, ¿El problema? Que tenía dicho
campo replicado por cada instancia de mi tabla liga. La solución que
pensé fue la de crear una variable de clase de la tabla League de esta
forma:

class League << ActiveRecord::Base
CLOSED = 0
OPEN = 1
@@alineations_state = CLOSED

def open_teams
@@alineations_state = OPEN
end

def close_teams
@@alineations_state = CLOSED
end

def opened_teams?
@@alineations_state == OPEN
end

def closed_teams?
@@alineations_state == CLOSED
end
end

Bien, tengo una acción en mi controlador de administración que realiza
lo siguiente:

def close_teams
League.close_teams
respond_to do |format|
format.hml {redirect_to(’/admin/leagues’)}
format.xml {head :ok}
end
end

def open_teams
League.open_teams
respond_to do |format|
format.hml {redirect_to(’/admin/leagues’)}
format.xml {head :ok}
end
end

Pues bien, no sé por qué esas acción no funciona. Las ejecuto pero se
queda con el valor con el que inicialice la variable de clase.

Sin embargo es curioso que si en la consola ejecuto: League.close_teams
y luego consulto League.closed_teams? funciona perfectamente, así como
con las acciones open. ¿En qué me estoy equivocando?

Carlos Belizón wrote:

Sin embargo es curioso que si en la consola ejecuto: League.close_teams
y luego consulto League.closed_teams? funciona perfectamente, así como
con las acciones open. ¿En qué me estoy equivocando?

Perdón los metódos de antes todos son de clase, vamos que llevan un
“self.” delante.

2009/5/28 Carlos Belizón [email protected]:

Ror-es mailing list
[email protected]
http://lists.simplelogica.net/mailman/listinfo/ror-es

Lo que intentas es una receta para el desastre.

Desde el punto de vista del lenguaje de programación Ruby lo que
intentas es totalmente correcto. Y por ello te funciona en la consola,
por ejemplo. Y te funcionará en controlador si justo después de
close_teams pones un closed_teams?. Pero…

Desde el punto de vista de programación para la web lo que intentas no
funciona. Peor aún, en desarrollo no te funciona (como ya has visto) y
puede que en produción te funcione unas veces y otras no. La razón:
cada vez que haces una petición web, tu aplicación se carga desde 0,
y es por eso por lo que siempre ves el valor inicial: el valor cambia
para la petición inicial, pero al llegar la siguiente petición se ha
cargado de nuevo la clase y el valor “ha vuelto” a su estado inicial.

Básicamente la solución es que todo lo que quieras que se mantenga
entre peticiones tienes que almacenarlo persistentemente (es decir, en
la base de datos) y recuperarlo de allí. No me parece recordar que
Rails proporcione ninguna forma estándar de almacenar variables de
clase en la base de datos, así que tendrás que buscar alguna solución
alternativa.

Suerte.

Daniel R. Troitiño wrote:

2009/5/28 Carlos Belizón [email protected]:

Ror-es mailing list
[email protected]
http://lists.simplelogica.net/mailman/listinfo/ror-es

Lo que intentas es una receta para el desastre.

Desde el punto de vista del lenguaje de programación Ruby lo que
intentas es totalmente correcto. Y por ello te funciona en la consola,
por ejemplo. Y te funcionará en controlador si justo después de
close_teams pones un closed_teams?. Pero…

Desde el punto de vista de programación para la web lo que intentas no
funciona. Peor aún, en desarrollo no te funciona (como ya has visto) y
puede que en produción te funcione unas veces y otras no. La razón:
cada vez que haces una petición web, tu aplicación se carga desde 0,
y es por eso por lo que siempre ves el valor inicial: el valor cambia
para la petición inicial, pero al llegar la siguiente petición se ha
cargado de nuevo la clase y el valor “ha vuelto” a su estado inicial.

Básicamente la solución es que todo lo que quieras que se mantenga
entre peticiones tienes que almacenarlo persistentemente (es decir, en
la base de datos) y recuperarlo de allí. No me parece recordar que
Rails proporcione ninguna forma estándar de almacenar variables de
clase en la base de datos, así que tendrás que buscar alguna solución
alternativa.

Suerte.

Muchas gracias, no sabía yo que era tan malísima idea la de almacenar en
una variable de clase ese estado.

Lo único que se me ocurre es crearme un modelo que se llame
ControlLeagues que creará una tabla con una sóla columna que sólo tendrá
una instancia para llevar el control del estado de las Ligas, ¿Alguien
tiene una idea mejor?

Si solo tienes que almacenar un flag y no quieres liarte con la base
de datos, siempre puedes crear un fichero txt en disco, o utilizar
memcached…

Saludos,

Isaac Feliu

On May 29, 2009, at 12:17 AM, Carlos Belizón wrote:

Yo no creo que sea tan mala idea meter ese flag en la base de datos,
pero no lo haria en otro modelo. Por lo que veo el modelo League se
debe estar consultando constantemente a la BD, si le pones un campo
mas donde guardar el flag abierta/cerrada no necesitaras hacer una
consulta extra cada vez para saber el estado.

¿El problema? Que tenía dicho campo replicado por cada instancia de mi tabla liga.
Eso no es un problema, es lo logico, cada liga deberia tener su flag,
ya que en el mismo momento una liga puede estar abierta y otra no. O
el estado abierto/cerrado es igual en todo momento para todas las
ligas que tengas en la BD???

El día 29 de mayo de 2009 0:24, Isaac Feliu Pérez
[email protected] escribió:

puede que en produción te funcione unas veces y otras no. La razón:
Rails proporcione ninguna forma estándar de almacenar variables de
ControlLeagues que creará una tabla con una sóla columna que sólo


Ror-es mailing list
[email protected]
http://lists.simplelogica.net/mailman/listinfo/ror-es

2009/5/28 Carlos Belizón [email protected]:

Veréis necesito controlar con un flag cuando se puede realizar varias
acciones (cambios, ventas, etc…), pues bien, en un principio lo
controlaba mediante un campo en una tabla, ¿El problema? Que tenía dicho
campo replicado por cada instancia de mi tabla liga.

Si todas las ligas tienen siempre el mismo estatus tienes dos
aproximaciones:

  1. Replicar el campo en los registros de todos modos (no bid deal)

  2. Tener un modelo persistente LeagueStatus, que haria las veces de
    “global” a la tabla de ligas

Primero iria a por esas soluciones que son sencillas y no introducen
nada adicional. La segunda puede significar una query mas, pero en
muchas aplicaciones esa query de mas no tiene la menor importancia.

Si es una configuración global yo tiraría por un fichero de
configuración rollo yaml:

f.