Esquema do banco de dados FuelPHP ORM para i18n, opiniões / sugestões

Enquanto esta questão pode sersemelhante para muitos outrasGostaria de pedir opiniões / sugestões sobre a melhor abordagem para o i18n specificaly no FuelPHP.

Então, aqui está o que eu tenho até agora:

Esquema de banco de dados # 1:

models (id, name_pt, name_es, name_en, description_pt, description_es, description_en)

Dados da amostra # 1:

(1, 'Modelo', 'Modelo', 'Model', 'Descrição do modelo', 'Descripción del modelo', 'Model description')

Prós:

Reto e simplesUma tabela por modeloNão há necessidade de usar o JOINUso de um método mágico para simplificar o acesso a dados:

 

public function & __get($property)
{
    if (array_key_exists($property, array('name', 'description')))
    {
        $property = $property.'_'.Session::get('lang_code');
    }

    return parent::__get($property);
}

Dessa forma, eu sou capaz de fazer chamadas:

$model->name;
$model->description;

ao invés de:

$model->{'name_'.Session::get('lang_code')};
$model->{'description_'.Session::get('lang_code')};

Contras:

Ter muitos idiomas / campos traduzidos pode ficar confuso.Adicionar um novo idioma implica adicionar novos campos à tabelaO método mágico só funciona quando já temos uma instância / objeto ORM. Para buscar uma instância ORM através doconstrutor de consulta ordenada por um campo traduzido, ainda é necessário um código como:

 

Model_Model::query()
    ->order_by('name_'.Session::get('lang_code'))
    ->get();

Esquema de banco de dados # 2:

languages (id, code, name)
models (id)
i18n_models (id, model_id, language_id, name, description)

Dados da amostra # 2:

-- languages
(1, 'pt', 'Português')
(2, 'es', 'Español')
(3, 'en', 'English')

-- models
(1)

-- i18n_models
(1, 1, 1, 'Modelo', 'Descrição do modelo')
(2, 1, 2, 'Modelo', 'Descripción del modelo')
(3, 1, 3, 'Model', 'Model description')

Prós:

Melhor organização de dadosAdicionando um novo idioma é um piscar de olhosComo na primeira abordagem, também podemos ter acesso direto aos dados usando oconjunto() método para preencher a matriz $ _custom_data:

 

$i18n = Model_I18n_Model::query()
    ->where('model_id', $model->id)
    ->where('language_id', Session::get('lang_code'))
    ->get_one();

$model->set(array(
    'name' => $i18n->name,
    'description' => $i18n->description
));

Contras:

A complexidade aumentaUm JOIN ou uma segunda consulta deve ser usadaUma tabela extra para cada modelo é necessária

Esquema de banco de dados # 3:

Em outras perguntas, eu vi pessoas sugerirem o uso de uma tabela i18n central para todas as traduções, usando uma linha para cada tradução que um modelo possui.

Prós:

Única tabela para i18n compartilhada entre modelosAdicionar um novo idioma deve ser fácil, como na abordagem anterior

Contras:

A complexidade aumenta durante a busca de dados, exigindo um JOIN para cada texto traduzido que um modelo tenhaNós poderíamos tentar usarContêineres EAV com esta abordagem, embora isso use uma chave / valor para o mapeamento, mas neste caso em particular, também temos que usar o language_id para buscar a tradução correta.

Pessoalmente, eu prefiro a segunda abordagem. Quais outras vantagens / desvantagens você vê? Alguém implementou o i18n de uma maneira diferente no FuePHP? Compartilhe suas ideias :)

questionAnswers(1)

yourAnswerToTheQuestion