Laravel: Accessors (аксессоры) и Mutators (мутаторы).
Доброго времени суток. Очередная статья из серии фишек Laravel. И в данной статье мы познакомимся с такими понятиями в Laravel, как accessors (аксессоры) и mutators (мутаторы) и применим их на практике. Ну, что приступим.
Исходные данные у нас есть таблица users:
Т.е. таблица содержит 5 полей:
- Id – ID
- first_name – имя пользователя
- last_name – фамилия пользователя
- created_at – дата создания записи
- updated_at – дата изменения записи
Давайте создадим модель User. Для этого вводим команду
php artisan make:model User
И добавляем в модель следующий код:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model { protected $table = 'users'; protected $fillable = ['first_name','last_name']; }
Тут объяснять, думаю, нечего. Единственное свойство $table в нашем случае определять не обязательно, т.к. имя модели совпадает с именем таблицы во множественном числе.
Теперь давайте создадим контроллер UserController, который будет получать данные из нашей модели и передавать их во вьюшку.
Для создания контроллера выполним следующую команду:
php artisan make:controller UserController
И добавим в него следующий код:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\User; class UserController extends Controller { public function index() { $users = User::all(); return view('users', ['users' => $users]); } }
Тут тоже ничего сложного, создаем метод index, в котором получаем всех пользователей и передаем их во вьюшку users. Давайте создадим вьюшку users.blade.php и добавим в нее следующий код:
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <title>Список пользователей</title> <style type="text/css"> td { border: 1px solid; padding: 5px; } </style> </head> <body> <table> <tr> <td>Имя</td> <td>Фамилия</td> <td></td> </tr> @foreach($users as $user) <tr> <td>{{ $user->first_name }}</td> <td>{{ $user->last_name }}</td> <td></td> </tr> @endforeach </table> </body>
Теперь осталось добавить роут:
Route::get('','UserController@index')->name('users');
Добавим несколько записей в таблицу users:
И проверим:
Отлично, теперь нам надо вывести в одном поле полное имя и фамилию. Мы можем сделать так:
… <td> {{ $user->last_name }} {{ $user->first_name }} </td> …
Но это не всегда удобно. Ведь вывод полного имени может встречаться во многих местах. И в Laravel к нам на помощь приходят accessors.
Accessor (аксессор) в Laravel
Давайте в модели User создадим еще один метод:
… public function getFullNameAttribute() { return $this->last_name." ".$this->first_name; }
И теперь для получения полного имени мы можем использовать
$user->full_name
Давайте поправим нашу вьюшку:
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <title>Список пользователей</title> <style type="text/css"> td { border: 1px solid; padding: 5px; } </style> </head> <body> <table> <tr> <td>Имя</td> <td>Фамилия</td> <td>Полное имя</td> </tr> @foreach($users as $user) <tr> <td>{{ $user->first_name }}</td> <td>{{ $user->last_name }}</td> <td>{{ $user->full_name }}</td> </tr> @endforeach </table> </body> </html>
Проверяем:
Отлично все работает. Но есть один важный момент. Вы не можете использовать это имя атрибута в Eloquent. Т.е. если вы захотите сделать сортировку по full_name
User::orderBy('full_name')->get();
Код не сработает. Данный атрибут работает только в коллекции. И для того, чтобы сделать сортировку по full_name необходимо вначале получить коллекцию, а затем выполнить сортировку:
User::all()->orderBy('full_name');
Mutators (мутаторы) в Laravel
В таблице у нас есть два поля Имя и Фамилия и мы хотим, чтобы в них все символы были в нижнем регистре, кроме первого. И тут в Laravel на помощь нам приходят мутаторы.
Давайте в модели User создадим еще два метода:
public function setFirstNameAttribute($value) { $str = mb_strtolower($value); $this->attributes['first_name'] = mb_strtoupper(mb_substr($str, 0, 1)).mb_substr($str, 1); } public function setLastNameAttribute($value) { $str = mb_strtolower($value); $this->attributes['last_name'] = mb_strtoupper(mb_substr($str, 0, 1)).mb_substr($str, 1); }
Отлично, теперь в контроллере UserController создадим два метода для добавления пользователя.
Метод create:
public function create() { return view('create'); }
Данный метод возвращает вьюшку, которая выводит форму для добавления.
Метод store:
public function store(Request $request) { $first_name = $request->first_name; $last_name = $request->last_name; $user = new User; $user->first_name = $first_name; $user->last_name = $last_name; $user->save(); return redirect()->route('users'); }
Данный метод сохраняет данные.
Давайте создадим вьюшку create.blade.php
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <title>Добавление данных</title> <link href="{{ asset('css/bootstrap.min.css') }}" rel="stylesheet"> </head> <body> <div class="container"> <form method="POST" action="{{ route('users.store') }}"> {{ csrf_field() }} <div class="form-group"> <label for="first_name">Введите имя</label> <input class="form-control" id="first_name" placeholder="Имя" name="first_name"> </div> <div class="form-group"> <label for="last_name">Введите фамилию</label> <input class="form-control" id="last_name" placeholder="Фамилия" name="last_name"> </div> <button type="submit" class="btn btn-default">Добавить</button> </form> </div> </body> </html>
Теперь добавим два роута:
Route::get('/add','UserController@create')->name('users.create'); Route::post('/add','UserController@store')->name('users.store');
Проверяем:
Теперь вводим данные:
Я специально ввел «имя» все символы в нижнем регистре, а «ФАМИЛИЯ» в верхнем регистре. Жмем добавить.
Отлично! Все работает.
Заключение.
В данной статье мы рассмотрели accessors и mutators в Laravel, которые очень похожи на методы getter и setter в ООП. Также привели примеры использования аксессора и мутаторов.