Bueno, para muestras, unos cuántos botones.
schema.yml de symfony:
START entity ARCHIVO
archivo:
_attributes: { phpName: Archivo, isI18N: true, i18nTable:
archivo_i18n }
id: { type: integer, required: true, autoIncrement: true,
primaryKey:
true }
path: { type: varchar, size: 255 }
mime_type: { type: varchar, size: 20 }
created_at: { type: timestamp }
updated_at: { type: timestamp }
archivo_i18n:
_attributes:{ phpName: ArchivoI18n }
id: { type: integer, required: true, primaryKey: true, foreignTable:
archivo, foreignReference: id, onDelete: cascade }
culture: { isCulture: true, type: varchar, size: 7, required: true,
primaryKey: true }
nombre: { type: varchar, size: 150 }
descripcion: { type: varchar, size: 255 }
END entity ARCHIVO
Que se traduce en el siguiente SQL (para MySQL):
CREATE TABLE archivo
(
id
INTEGER NOT NULL AUTO_INCREMENT,
path
VARCHAR(255),
mime_type
VARCHAR(20),
created_at
DATETIME,
updated_at
DATETIME,
PRIMARY KEY (id
)
)Type=InnoDB;
CREATE TABLE archivo_i18n
(
id
INTEGER NOT NULL,
culture
VARCHAR(7) NOT NULL,
nombre
VARCHAR(150),
descripcion
VARCHAR(255),
PRIMARY KEY (id
,culture
),
CONSTRAINT archivo_i18n_FK_1
FOREIGN KEY (id
)
REFERENCES archivo
(id
)
ON DELETE CASCADE
)Type=InnoDB;
Lógicamente la clave de la tabla auxiliar es el ‘id’ del archivo y
‘culture’…
(Habrá quién proponga que exista una tabla “Cultures” con todos los
lenguajes, y se hagan tablas de cruce entre lenguajes y modelos
concretos…
Pero la simplificación que se usa en symfony de usar las convenciones de
locales me parece mejor, nos ahorra querys y es perfectamente válida -por
que no tiene sentido que pongamos dos cultures iguales con valores de
nombre
diferentes…-)
Desde luego, la solución que propone Globalize:
http://www.saimonmoore.net/2007/3/17/globalize-internal-storage-mechanism
Me parecen ambas, un tanto “malas”; en la anterior a la 1.2, guardaba
las
traducciones en una tabla de traducciones:
Before the for-1.2 release, Globalize used an external table
(globalize_translations) to store translations
Y ahora lo guarda mediante el "“Internal Storage Mechanism”, dónde está
duplicando campos dentro de una misma tabla.
Si miramos la primera opción de Globalize, vemos que la tabla de
traducciones puede llegar a ser enorme, pues tal y cómo lo explican
ahí,esa tabla es para toda la aplicación… Entiendo que para todos los modelos
O;)
La segunda, implica que un cambio de número de idiomas en tu
aplicación,tengas que volver a tocar tu código; si eres tu el que mantiene el sitio
web, sí, ganas en rapidez a la hora de ejecutar consultas… Pero como no
lo
mantengas tu, y quieras dar una solución multilenguaje a tu cliente final,
pues no me parece una solución acertada…
Ciertamente, la segunda solución es la más KISS; pero… El precio, a mi
entender, es alto.
Si queremos dotar a nuestra aplicación de un soporte multilenguaje REAL,
debería de ser posible agregar/eliminar lenguajes con facilidad a la
misma,
sin que tengamos que tocar el código fuente; por ello, sigo pensando que la
solución de Symfony es, por el momento, superior.
Y si lo que queremos es hacer la traducción de pocos términos, francamente,
con un gettext se va que chuta… Sin tanta
complicación.
Repito, pensando en la escalabilidad, entiendo que la solución de utilizar
dos tablas es bastante superior; y en cuánto a rendimiento, la diferencia
…
Database changed
mysql> select * from archivo;
…
83 rows in set (0.0161 sec)
mysql> SELECT * FROM archivo INNER JOIN archivo_i18n ON archivo.id =
archivo_i18n.id
…
83 rows in set (0.0181 sec)
Vamos, no creo que la diferencia de rendimiento sea un hándicap tan
grande.
Un saludo
De: Iñigo Sola Núñez [mailto:[email protected]]
Enviado el: miércoles, 05 de septiembre de 2007 21:25
Para: [email protected]; La lista sobre Ruby On Rails
(rubyonrails.com) en castellano
Asunto: Re: [Ror-es] Multi - idiomas
Esta solución que propones, Iñigo, me parece una cagada, con perdón.
Para gustos los colores, pero veamos tu propuesta…
Es el planteamiento que hace Globalize, y me parece HORROROSO.
De paso, ya que estamos, aprovecho yo también para preguntar a ver si hay
algo parecido a lo que existe en Symfony (seguramente exista)
No me consta
En Symfony, si se tiene el modelo:
Producto { id, nombre, descripcion, created_at }
Y lo quieres internacionalizar, creas una tabla i18n,
así:
Producto { id, created_at }
Producto_i18n { culture, producto_id, nombre, descripcion }
Si nos ponemos un poco quisquillosos, salta a la vista que tu solución es
menos eficiente. Almacenas un campo extra para la relación, por no hablar
de los join que habría que hacer en tiempo de ejecución.
Dónde en el modelo Producto_i18n es PK clave principal “culture” (es, etc
etc…) y “producto_id” FK clave externa
No se si entiendo tu planteamiento. ¿‘Culture’ es la clave principal? De
ser
así no podrás tener mas de un producto de cada idioma.
De cualquier forma no entiendo esta desnomarlización que propones, sobre
todo no veo las ventajas que aporta,… no las veo.
Es evidente que así tenemos un gestor de productos dinámico en cuánto a
lenguajes posibles de traducción.
Y lo mejor de todo, es que esto se integra en el ActiveRecord de
Symfony; si
por ejemplo queremos el nombre del producto en español, haríamos:
$producto = ProductoPeer::getByPK(1);
$producto->setCulture(‘es’);
echo $producto->getNombre();
En inglés:
$producto->setCulture(‘en’);
echo $producto->getNombre();
Puedes conseguir lo mismo diseñandote un sencillo procedimiento a nivel de
modelo. (y ahorrándote hacer joins)
Y así sucesivamente…
¿Existe algo así para RoR? Yo creo que tiene que existir… El caso es
¿dónde? 
No me costa que exista.
Un saludo a todos y gracias
Igualemente.