Фон
У меня есть интернационализированная БД, которая хранит свои строки для разных языков, например:
products
id
price
product_translation
id
product_id
language_id
name
description
languages
id
name (e.g. 'English', 'German')
code (e.g. 'en', 'de')
С соответствующими моделями для каждой таблицы (Product, ProductTranslation, Language). На мой взгляд, я хочу получить список продуктов, как это:
// get first 20 products, list name and price.
@foreach(Product::take(20)->get() as $product)
{{$product->translations->name}} {{$product->price}}
@endforeach
проблема
Мое приложение будет возвращать названия продуктов в соответствии с текущими App::getLocale()
установлен на (т.е. en
а также de
).
Я только начинаю с Eloquent от Laravel, я не уверен, как указать правильные отношения (или, если я вообще делаю это правильно).
Моя попытка
Я указал OneToMany
отношения между Product
а также ProductTranslation
:
class Product extends \Eloquent {
protected $with = ['translations'];
public function translations()
{
return $this->hasMany('ProductTranslation');
}
}
Это работает нормально, но вернет все переводы (нам нужна только текущая локаль).
Затем я указываю OneToOne
отношения между ProductTranslation
а также Language
:
class ProductTranslation extends \Eloquent {
protected $with = ['language'];
public function language()
{
return $this->hasOne('Language')
->where('code', App::getLocale());
}
}
Я знаю, что это не работает, и я озадачен тем, что делать дальше. У кого-нибудь есть более чистый подход?
class ProductTranslation extends \Eloquent {
protected $with = ['language'];
public function language()
{
return $this->hasOne('Language');
}
}
В маршруте или контроллере
ProductTranslation::language()->where('code', '=', App::getLocale())->get();
Чтобы сохранить это в модели, сделайте это
public static function getLocale()
{
return static::language()->where('code', '=', App::getLocale())->get();;
}
Вызовите функцию, используя ProductTranslation::getLocale()
В Laravel есть встроенная система переводов, и, немного поработав, вы можете заставить ее работать с базой данных, однако, вероятно, это не то, для чего она была разработана.
Вы не можете получить те, которые хотите, потому что отношения основаны на идентификаторах (внешних ключах), а не на строковых ограничениях или аналогичных.
По вашему мнению, вы можете посмотреть на фильтрацию тех, которые не соответствуют языковому коду, который вы хотели, используя filter (): http://laravel.com/docs/4.2/eloquent#collections
Или Вы могли бы рассмотреть перемещение переводов в надлежащее место как жестко закодированное: http://laravel.com/docs/4.2/localization и если это невозможно, вы можете посмотреть переводы из базы данных, используя метод, описанный в этой ссылке. В конце концов он просто возвращает массив переводов и не заботится о том, как вы создали массив, жестко запрограммированный или из базы данных.