database - relaciones - yii relations
¿Cómo usar Yii con un modelo de base de datos multilingüe? (3)
Tengo problemas para conseguir que los datos de mi base de datos que creé sean completamente multilingües, y espero que alguien aquí pueda ayudarme.
He dividido todas mis tablas en 2 partes; la tabla "universal" (no contiene ningún texto que deba traducirse) y la tabla que contiene todos los campos que deben traducirse con sus traducciones.
Tablas de ejemplo:
base_material
id
picture
base_material_i18n
base_material_id
localization_id
name
description
review_status
review_notes
localization
id
language_name
Consulta para obtener las traducciones (usando English (en) como un lenguaje alternativo si no hay traducción disponible):
SELECT o.id
, o.type
, o.code
, o.position
, ifnull(t.name,d.name) name
, ifnull(t.description,d.description) description
FROM base_material o
INNER JOIN base_material_i18n d
ON ( o.id=d.base_material_id)
LEFT OUTER JOIN base_material_i18n t
ON ( d.base_material_id=t.base_material_id AND t.localization_id=''nl'' )
WHERE d.localization_id=''en''
Mi pregunta es cómo puedo obtener automáticamente esas traducciones (con el lenguaje de retorno como en esta consulta) adjuntas a mi modelo en Yii cuando estoy buscando los objetos de base_material. (Esta es solo 1 tabla de ejemplo, pero casi todas mis tablas (20+) están compiladas de esta manera, así que si es posible necesitaría algo flexible)
Un ejemplo de un sistema existente que usa lo que necesitaría es Propel: http://propel.posterous.com/propel-gets-i18n-behavior-and-why-it-matters
¿Alguna idea de cómo hacer eso? Revisé las extensiones Yii existentes con respecto a los sitios multilingües (como el Registro activo multilingüe ), pero todos utilizan un diseño de base de datos diferente (información general + lenguaje alternativo en la tabla principal, traducciones en la tabla i18n), y estoy No estoy seguro de cómo cambiar esas extensiones para usar mi tipo de modelo de base de datos.
Si alguien sabe de una forma de cambiar esa extensión existente para que pueda usar mi tipo de esquema DB, entonces eso sería absolutamente brillante y probablemente la mejor manera de hacerlo.
Editar: he agregado una recompensa porque todavía no puedo encontrar nada sobre cómo dejar que Propel trabaje con Yii (existe una extensión para Doctrine, pero Doctrine tampoco admite este tipo de modelo de DB con traducciones), ni tampoco más información sobre cómo lidiar con esto usando una extensión Yii existente o con alcances.
Editar : 98 veces visto pero solo 3 votaciones ascendentes y 1 comentario. No puedo evitar sentir que estoy haciendo algo mal aquí, ya sea en mi pregunta o en el diseño de la aplicación / base de datos; o ese o mi problema es muy único (lo cual me sorprendería, ya que no creo que mi diseño de base de datos multilingüe sea tan absurdo ;-). Entonces, si alguien sabe de una mejor solución integral para sitios multilingües con Yii y / o Propel (aparte de las extensiones actuales que realmente no me gustan debido a la duplicación de campos de texto) o algo similar, háganmelo saber. también.
¡Gracias por adelantado!
También estoy buscando una solución genérica para implementar i18n en los modelos Yii. Recientemente, elegí un esquema de base de datos muy similar para un proyecto como tú. La única diferencia es que no estoy usando una tabla de idiomas separada, almaceno la información del idioma en la tabla i18n.
La siguiente solución es sin una declaración de SQL personalizada, pero creo que esto podría implementarse con params de relación, de todos modos, si está trabajando con una clave externa en su base de datos (por ejemplo, MySQL InnoDB) gii creará relaciones entre su tabla base_material y base_material_i18n , me gusta
class BaseMaterial extends CActiveRecord
public function relations()
{
return array(
''baseMaterialI18ns'' => array(self::HAS_MANY, ''base_material_i18n'', ''id''),
);
}
class BaseMaterialI18n extends CActiveRecord
public function relations()
{
return array(
''baseMaterial'' => array(self::BELONGS_TO, ''base_material'', ''id''),
);
}
Ahora podrá acceder a sus traducciones utilizando la notación de objeto para las relaciones.
$model = BaseMaterial::model()->with(''baseMaterialI18ns'')->findByPk(1);
foreach($model->baseMaterialI18ns AS $translation) {
if ($translation->language != "the language I need") continue:
// do something with translation data ...
}
Pensé en crear un comportamiento o una clase base para los modelos que actuarían como ayudantes para gestionar las traducciones: pseudocódigo:
I18nActiveRecord extends CActiveRecord
protected $_attributesI18n;
// populate _attributesI18n on query ...
public function __get($name) {
if(isset($this->_attributesI18n[''language_I_need''][$name]))
return $this->_attributesI18n[$name];
else if(isset($this->_attributesI18n[''fallback_language''][$name]))
return $this->_attributesI18n[$name];
else
parent::__get();
}
Hay más trabajo por hacer para encontrar el registro necesario de i18n, también podría limitar aún más la opción con () para mejorar el rendimiento y reducir el análisis en el lado de PHP.
Pero puede haber diferentes casos de uso para determinar el valor, por ejemplo, todas las traducciones, la traducción o el repliegue, sin recuperación (valor vacío). Los escenarios podrían ser útiles aquí.
PD: ¡Me gustaría un proyecto de Github !
Puede intentar utilizar una extensión CRUD multilingüe simple. es muy simple de usar y modificar. solo necesita agregar un campo de idioma a su tabla. basta con ver la descripción aquí: http://all-of.me/yii-multilingual-crud/ está en estado alfa, pero probó en algunos proyectos. puede modificarlo fácilmente o contactar al autor para arreglar o agregar funciones
¿Has probado http://www.yiiframework.com/extension/i18n-columns/ (basado en http://www.yiiframework.com/extension/stranslateablebehavior/ )?
Es un enfoque alternativo, más simple, agregando nuevos campos de tabla en el estilo de {campo} _ {código de idioma}, y luego configurando el campo traducido en el modelo original a la traducción del idioma actual en afterFind.
Básicamente, lo pondrá en marcha con campos traducibles con el contenido traducido que se va a buscar "automáticamente", para bien y para mal :). Agregar y eliminar idiomas (= columnas) se realiza mediante migraciones.