Как настроить коллекцию в Laravel в соответствии с требуемым форматом?

Как изменить логику локализации в системе на Laravel так, чтобы обращение к значениям полей можно было осуществлять по коду языка, например, {{$category->locale["en"]['field_value']}}, вместо использования индекса, {{$category->locale[0]['field_value']}}?
  • 19 января 2024 г. 18:48
Ответы на вопрос 2
Для настройки коллекции в Laravel в соответствии с требуемым форматом, можно воспользоваться методом `transform` или `map`, которые позволяют изменить каждый элемент коллекции по определенному правилу:

Пример использования `transform` для коллекции:

```php
$collection = collect([1, 2, 3, 4, 5]);

$modified = $collection->transform(function ($item, $key) {
    return $item * 2;
});

// $modified теперь будет содержать [2, 4, 6, 8, 10]
``` 

Чтобы изменить логику локализации в системе на Laravel так, чтобы обращение к значениям полей осуществлялось по коду языка, можно использовать дополнительный атрибут в модели, который будет обрабатывать данные о локализации.

Допустим, у вас есть поле `locale` в таблице `categories`, которое содержит JSON с локализованными значениями, например:

```json
{
    "en": {"field_value": "English Value"},
    "ru": {"field_value": "Russian Value"}
}
```

Сначала необходимо добавить атрибут `$casts` в модель `Category`:

```php
class Category extends Model
{
    protected $casts = [
        'locale' => 'array', // Указываем, что поле 'locale' должно быть массивом
    ];

    // Дополнительно, можно создать аксессор для удобства
    public function getLocaleAttribute($value)
    {
        return json_decode($value, true) ?: [];
    }
}
```

Теперь вам доступен доступ к полям через код языка:

```php
$category = Category::find($id);
echo $category->locale['en']['field_value']; // Выведет "English Value"
```

Вы можете использовать данный подход прямо в шаблоне Blade:

```blade
{{ $category->locale['en']['field_value'] }}
```

Если вы хотите безопасно обращаться к значениям и избежать ошибок при отсутствующем ключе языка или значении, то рассмотрите использование хелпера `array_get()` или опционального объекта доступа `optional()`:

```blade
{{ array_get($category->locale, 'en.field_value', 'Default Value') }}
```

или с Laravel 7+:

```blade
{{ Arr::get($category->locale, 'en.field_value', 'Default Value') }}
```

или используя optional:

```blade
{{ optional($category->locale)['en']['field_value'] ?? 'Default Value' }}
```

Есть и альтернативная стратегия, когда вы создаете в модели методы для каждого возможного поля локализации:

```php
class Category extends Model
{
    // ...

    public function getTitleAttribute()
    {
        $locale = app()->getLocale(); // Получаем текущий язык приложения
        return $this->locale[$locale]['title'] ?? $this->locale['en']['title'] ?? 'Default Title';
    }
}
```

После этого вы можете вызывать `$category->title`, и это будет возвращать значение для текущего языка, с фоллбэком на английский язык или 'Default Title'.

Поиграв с этими подходами, вы сможете настроить локализацию в системе Laravel под свои конкретные задачи.
1. Создайте scope для модели Locale аля 

2. Создайте middleware аля AddLocaleScope

И вешайте их на все контроллеры где нужна подгрузка локали.

Можно другой вариант. Привести отношения у модели Category


И юзать когда нужна текущая локаль

И когда нужны все локали
$categories = Category::with('locales')->get();
Похожие вопросы