Como usar una variable en un layout

Veréis tengo el siguiente código en un layout:

<% if !current_user.club.season.round_actual.nil? %>


<% match = current_user.club.season.round_actual.get_match(@club)
%>
<%= “#{h(match.local.name)} #{match.local_goals}
- #{h(match.guest.name)} #{match.guest_goals}” %>

<% end %>

Pero veo bastante mal tener que declarar una variable dentro de una
vista, ¿Cómo puedo sacarla del layout? ¿Dónde he de escribir el código?

En el controlador creo yo ¿no?

El 12 de mayo de 2009 18:49, Carlos Belizón <
[email protected]> escribió:

Andrés Gutiérrez wrote:

En el controlador creo yo ¿no?

El 12 de mayo de 2009 18:49, Carlos Belizón <
[email protected]> escribió:

¿Pero en qué parte? Teniendo en cuenta que el layout se ejecuta que
cualquier acción, ¿Dónde he de recuperar el valor?

Si la variable match la necesitas en todas las acciones de todos los
controladores, en el aplication controller hace algo asi

class ApplicationController < ActionController::Base
before_filter :set_match

def set_match
@match = current_user.club.season.round_actual.get_match(@club)
end

y la tendras disponible en cualquier vista

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


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

Fernando C. wrote:

Mejor aún:

class ApplicationController < ActionController::Base
before_filter :set_match

def set_match
if !current_user.club.season.round_actual.nil?
@match = current_user.club.season.round_actual.get_match(@club)
end
end

Hey, muchas gracias, no sé como no se me ocurrió esa “chorrada”. Acabas
de salvarme la vida ;).

Mejor aún:

class ApplicationController < ActionController::Base
before_filter :set_match

def set_match
if !current_user.club.season.round_actual.nil?
@match = current_user.club.season.round_actual.get_match(@club)
end
end


<%- if @match -%>


<%= “#{h(@match.local.name)} #{@match.local_goals}
- #{h(@match.guest.name)} #{@match.guest_goals}” %>

<%- end -%>

Xavier N. wrote:

Te queria comentar también que estan que esta

current_user.club.season.round_actual.nil?

es una condicion demasiado complicada para una vista. Ahi parece que
sea necesario un metodo en User que encapsule lo que significa
club.season.round_actual.nil?, y una variable en el controller que
haga de simple flag para el if.

Hey, muchas gracias, he hecho lo que dices y el código ahora es
muchísimo más legible.

Te queria comentar tambien que esta

current_user.club.season.round_actual.nil?

sea necesario un metodo en User que encapsule lo que significa
club.season.round_actual.nil?, y una variable en el controller

de hecho, esa condición no es solamente muy complicada para una vista,
sino para cualquier sitio. Atendiendo a la ley de demeter (don’t talk to
strangers), deberías ejecutar métodos solamente sobre tu objeto o sobre
los objetos inmediatamente conectados a él. Es decir, que podrías hacer
algo como

class User
def round_actual?
club.round_actual?
end
end

y dentro de club

class Club
def round_actual?
season.round_actual?
end
end

y dentro de season

class Season
def round_actual?
round_actual.nil?
end
end

Aplicando esto, tu código es más robusto de cara a posibles cambios en
el futuro y como efecto colateral te permite realizar los tests de forma
más simple (para probar el objeto User no necesitas tener un
club/season/round_actual. Te vale con el método round_actual?)

saludos,

j


javier ramírez

…i do ruby on rails development in madrid, spain, at
http://www.aspgems.com
…you can find out more about me on http://formatinternet.wordpress.com
and http://workingwithrails.com/person/5987-javier-ramirez

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

Veréis tengo el siguiente código en un layout:

<% if !current_user.club.season.round_actual.nil? %>

Te queria comentar tambien que esta

current_user.club.season.round_actual.nil?

es una condicion demasiado complicada para una vista. Ahi parece que
sea necesario un metodo en User que encapsule lo que significa
club.season.round_actual.nil?, y una variable en el controller que
haga de simple flag para el if.

class Season
def round_actual?
round_actual.nil?
end
end

Aplicando esto, tu código es más robusto de cara a posibles cambios en

antes de que nadie me diga nada :wink: … Es muy posible que puedas usar
directamente :delegate para ahorrarte los métodos intermedios y dejar
que ruby lo haga por ti. El efecto final es el mismo


javier ramírez

…i do ruby on rails development in madrid, spain, at
http://www.aspgems.com
…you can find out more about me on http://formatinternet.wordpress.com
and http://workingwithrails.com/person/5987-javier-ramirez

javier ramirez wrote:

de hecho, esa condición no es solamente muy complicada para una vista,
sino para cualquier sitio. Atendiendo a la ley de demeter (don’t talk to
strangers), deberías ejecutar métodos solamente sobre tu objeto o sobre
los objetos inmediatamente conectados a él. Es decir, que podrías hacer
algo como

class User
def round_actual?
club.round_actual?
end
end

y dentro de club

class Club
def round_actual?
season.round_actual?
end
end

y dentro de season

class Season
def round_actual?
round_actual.nil?
end
end

Aplicando esto, tu código es más robusto de cara a posibles cambios en
el futuro y como efecto colateral te permite realizar los tests de forma
más simple (para probar el objeto User no necesitas tener un
club/season/round_actual. Te vale con el método round_actual?)

Eso es muy bonito en teoría, pero por cada nivel vas a hacer un acceso a
base de datos: tu aplicación irá lenta, y tu servidor irá cargado. Lo
suyo para este caso sería replicar la información tantas veces como haga
falta, y que todas las tablas (User, Club, Season) tuvieran un campo
“round_actual” (o mejor: “jornada_actual” o “current_round”, para no
hablar espanglis) que se pudiera consultar directamente con un único
acceso. Eso complica un poco el proceso de cambio de jornada, pero la
ganancia en simplicidad y velocidad del código lo compensa con creces…
Más que nada, porque van a haber muchísmos más READs de la jornada
actual que WRITEs, por lo que conviene optimizar el READ.

s2

Eso es muy bonito en teoría, pero por cada nivel vas a hacer un acceso a
base de datos: tu aplicación irá lenta,
no tiene porqué. Si al cargar el user has lanzado los includes
necesarios, no estás ejecutando más que la consulta inicial a la db. De
hecho tal cuál funciona Rails ahora mismo, aunque uses includes vas a
acabar teniendo n consultas (una por cada tabla asociada) así que sería
lo mismo.

En realidad he entrado al thread no por el caso concreto de estos
modelos o del rendimiento (que no parece crítico en esta aplicación),
sino por la parte de tener un statement excesivamente complicado que te
fuerza a tener un acoplamiento grande.

Creo que es interesante dedicar tiempo a que tu código quede bien
estructurado e incluso en algunas ocasiones aunque resultase en un
rendimiento peor (que no tiene porqué ser el caso esta vez)

saludos,

j


javier ramírez

…i do ruby on rails development in madrid, spain, at
http://www.aspgems.com
…you can find out more about me on http://formatinternet.wordpress.com
and http://workingwithrails.com/person/5987-javier-ramirez

Eso es muy bonito en teoría, pero por cada nivel vas a hacer un acceso a
base de datos: tu aplicación irá lenta,

La solucion que te ha comentado Javier, a parte de estar mucho mejor
que la tuya en cuanto, no solo a “belleza del codigo” sino a
estructuracion, no es mas lenta que la tuya, pruebalo.

No solo tiene que estar bien estructurada, también habría que ver si se
puede optimizar algo mas.

No hacer llamadas a la DB desde una vista por ejemplo puede hacer un
gran
efecto, y esto lo consigue con un simple “include”.

Ejem: User.find :all, :include => [:profiles, friends]

Si pudieras pegarnos un trozo del log de una vista de Verema seguro que
podríamos ayudarte a optimizarla.

2009/5/18 Fernando C. [email protected]

javier ramirez wrote:

no tiene porqué. Si al cargar el user has lanzado los includes
necesarios, no estás ejecutando más que la consulta inicial a la db. De
hecho tal cuál funciona Rails ahora mismo, aunque uses includes vas a
acabar teniendo n consultas (una por cada tabla asociada) así que sería
lo mismo.

O no me he explicado, o no me has entendido: mi propuesta es guardar una
copia del dato en la propia tabla (cachearlo permanentemente, vamos), y
eso supone que está accesible en una única consulta.

El rendimiento (que no parece crítico en esta aplicación).

Creo que es interesante dedicar tiempo a que tu código quede bien
estructurado e incluso en algunas ocasiones aunque resultase en un
rendimiento peor (que no tiene porqué ser el caso esta vez)

Emili Parreño wrote:

La solucion que te ha comentado Javier, a parte de estar mucho mejor
que la tuya en cuanto, no solo a “belleza del codigo” sino a
estructuracion, no es mas lenta que la tuya, pruebalo.

De la mejor estructuración no tengo ninguna duda, y quizá sea cierto que
aquí el rendimiento no vaya a ser crítico (aunque a mí me gusta
optimizar el rendimiento por sistema, aun sin ser crítico). Pero en
cuanto a rendimiento, es algo que ya he probado, y no con logs, sino con
aplicaciones reales, http://www.verema.com/ y http://www.rankia.com/ ,
de más de millón y medio de páginas al mes…

Verema está hecha “bien estructurada”, pero me paso el tiempo
consultando para cada contenido cuál es el nombre del subtipo (vía
subtipo_id) y el nombre del autor (vía usuario_id). Para Rankia, estos
datos y algunos pocos más están cacheados en la tabla que frecuentemente
los consulta, rompiendo la “estructuración”… pero la diferencia de
resultados que da newrelic es apreciable:
Tiempo de respuesta: 160 => 105
Consumo de CPU, memoria y BBDD: 9,5%, 582 MB y 19,3% => 6,6%, 358 MB y
9,8%

(Datos de la media semanal del último informe de newrelic; ambas están
alojadas en la misma máquina y con la misma configuración)

Aparte de que no necesito que newrelic lo diga… con ver los logs de
desarrollo y las consultas a BBDD que se están generando en cada caso,
ya se nota.

s2

que yo sepa, desde mysql 5 ya metieron el tema de los triggers y
procedimientos almacenados(aunque no tengo ni idea si la implementación
es
comparable a la de postgres)

2009/5/20 Benjamín Cárdenas Salamandra [email protected]


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

Ceritium wrote:

No solo tiene que estar bien estructurada, también habría que ver si se
puede optimizar algo mas.

No hacer llamadas a la DB desde una vista por ejemplo puede hacer un
gran
efecto, y esto lo consigue con un simple “include”.

Ejem: User.find :all, :include => [:profiles, friends]

Si pudieras pegarnos un trozo del log de una vista de Verema seguro que
podríamos ayudarte a optimizarla.

2009/5/18 Fernando C. [email protected]

No creas que es sólo eso… te aseguro que las optimizaciones triviales,
y algunas no tan triviales, ya están hechas, y los índices en su sitio,
y todo bien repasado con el newrelic (muy recomendable) para encontrar y
corregir cuellos de botella. Pero mira por ejemplo la página índice del
foro de gastronomía:

Tengo que sacar los 25 últimos hilos, y para cada uno de ellos la última
respuesta, y para el inicio de hilo y la última respuesta tengo que
acceder al usuario correspondiente; con tablas de decenas de miles y
cientos de miles de registros, cada una de ellas. La SQL (una sola, of
course!!) está ya muy pulida… pero si le ahorras tener que cruzar los
contenidos (hilo y última respuesta) con la tabla usuarios, consigues
que vaya mejor. No es que así vaya mal, de hecho Verema tiene muy buenos
tiempos… pero Rankia los tiene aún mejores, y además no podría
mantener cinco Veremas en mi servidor, y sí que podría mantener cinco
Rankias.

s2

2009/5/22 Gunnar W. [email protected]

Saludos,

FLAMEBAIT ALERT! ¡DEJEN PASO A LOS CAZAFANTAMAS!

Vamos a cuidar un poco el lenguaje. Mysql no sería una base de datos
seria
si me la hubiese encontrado borracha y tirada en la calle hoy al venir a
trabajar (y si ella no tuviese festivo hoy)
Como no es el caso, dejémoslo en que tiene ventajas e inconvenientes. De
lo
contrario tenemos que armar un complejísimo conjunto de teorías para
entender cómo es que X se decanta por Mysql para montar Y (1) ,
descartando
que a) X no son serios b) no entienden de qué va el tema y c) Y no sea
un
éxito tecnológico/financiero/empresarial

Sobre lo de InnoDB, hay muchas discusiones interesantes donde te
encuentras
opiniones diversas, como por ejemplo:
““MyISAM is faster” is a myth propagated by benchmark junkies who have
no
experience with real-world applications.” (2)

Y dicho esto, vamos a cerrar el hilo, que el flamebait sin haber bebido
nada
antes me da ardor de estómago y las discusiones sobre “X IS TEH SUCK / Y
ROCKS” me provocan astenia metafísica

(1) http://www.mysql.com/customers/industry/?id=85
(2)
High Availability MySQL: InnoDB is faster, tcmalloc is nice

Borja Martín dijo [Wed, May 20, 2009 at 12:29:32PM +0200]:

que yo sepa, desde mysql 5 ya metieron el tema de los triggers y
procedimientos almacenados(aunque no tengo ni idea si la implementación es
comparable a la de postgres)

MySQL no es una base de datos seria. Y no, no lo digo de broma de
ninguna manera. Es una BD qu eno implementa decentemente el estándar
SQL; la integridad referencial ya existe, pero requiere que uses un
tipo de tabla ridículamente lento (lo de MyISAM vs. InnoDB). Hay
muchas condiciones que te llevan a valores sin sentido (p.ej. la fecha
00-00-0000 es válida)… Si quieres una base de datos de verdad, usa
PostgreSQL.

Saludos,


Gunnar W. - [email protected] - (+52-55)5623-0154 / 1451-2244
PGP key 1024D/8BB527AF 2001-10-23
Fingerprint: 0C79 D2D1 2C4E 9CE4 5973 F800 D80E F35A 8BB5 27AF