Laravel: как скопировать строку из таблицы используя Eloquent
Доброго времени суток. Это статья из серии фишки Laravel. Так в одной из статей «Установки значения столбцов базы данных по умолчанию в Laravel» мы рассмотрели, как установить дефолтные значения столбцов базы данных. А в этой статье рассмотрим, как скопировать строку из таблицы используя Eloquent.
Вводные данные у нас есть таблица orders, которая имеет следующую структуру.
Есть модель Order
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Order extends Model { protected $table = 'orders'; protected $fillable = [ 'name', ]; }
И настроено подключение к базе данных в .env.
Давайте создадим контроллер, который будет иметь три метода:
- Добавлять запись
- Выводить все записи
- И копировать запись
Создание контроллера в Laravel
Для создания контроллера используем команду artisan
php artisan make:controller OrderController --resource
Таким образом мы с вами создали контроллер OrderController с прписанными методами:
- index()
- create()
- store(Request $request)
- show($id)
- edit($id)
- update(Request $request, $id)
- destroy($id)
Нам осталось только прописать действия в методах
Создание метода для добавления записей
Для добавления новой записи у нас будут использоваться два метода create, который будет выводить форму добавления и store, который будет добавлять запись в базу данных.
Опишем метод create
public function create() { return view('create'); }
Метод просто возвращает вьюшку create.blade.php
Теперь давайте опишем метод store, который получает данные методом POST и записывет их в базу.
public function store(Request $request) { \App\Order::create(['name' => $request->name]); return redirect()->back()->with(['message' => 'Данные сохранены']); }
Вызываем статический метод create модели Order, который записывает в таблицу orders данные.
И дальше возвращаем редирект обратно откуда мы пришли, добавляя флеш сообщение «Данные сохранены»
Что такое флеш сообщение вы можете прочитать в документации Laravel
Создание view для добавления данных в Laravel
Создаем файл create.blade.php в resources/views и добавляем в него следующий код.
<!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"> @if(Session::get('message')) <div class="alert alert-success" role="alert">{{ Session::get('message') }}</div> @endif <form method="POST" action="{{ route('store') }}"> {{ csrf_field() }} <div class="form-group"> <label for="name">Введите название</label> <input class="form-control" id="name" placeholder="Название" name="name"> </div> <button type="submit" class="btn btn-default">Добавить</button> </form> </div> </body> </html>
Тут тоже ничего сложного нет. С помощью строки <link href=»{{ asset(‘css/bootstrap.min.css’) }}» rel=»stylesheet»> подключаем bootstrap. Дальше проверяем сессию message, которую мы передаем как флеш сообщение. Если она существует выводим ее содержимое.
Дальше создаем форму, где в качестве параметра action передаем роут с названием store.
Дальше используем хелпер csrf_field(), который в нашу форму помещает <input> с токеном, необходимо для защиты от межсайтовых запросов.
Ну в принципе и все. Осталось создать два роута. Открываем файл web.php, который находится в папке routes. И добавляем два именованных роута:
Route::get('/create', 'OrderController@create')->name('create'); Route::post('/create', 'OrderController@store')->name('store');
Теперь можем проверить и добавить несколько значений.
Сообщение о том, что данные добавлены выводится. Давайте перейдем в базу и посмотрим.
Отлично, данные сохранены в таблице. Теперь давайте создадим метод, который будет выводить все данные.
Создание метода для вывода данных
Для вывода всех данных будем использовать метод index контроллера OrderController. Давайте опишем его:
public function index() { $orders = \App\Order::all(); return view('index',['orders' => $orders]); }
В данном методе мы используем статический метод all() модели Order, который возвращает нам все данные из таблицы. И дальше возвращаем вьюшку index.blade.php, в которую передаем массив данных.
Создание view для отображения всех данных в Laravel
Создаем файл index.blade.php в каталоге resources/views
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <title>Добавление данных</title> <link href="{{ asset('css/bootstrap.min.css') }}" rel="stylesheet"> <style type="text/css"> table, th, td{ border: 1px solid; padding: 5px; } </style> </head> <body> <div class="container"> <table> <thead> <tr> <th>ID</th></pre> <pre> <th>Название</th> <th>Дата создания</th></pre> <pre> <th>Дата обновления</th> <th></th> </tr> </thead> @foreach($orders as $order) <tr> <td>{{ $order->id }}</td> <td>{{ $order->name }}</td> <td>{{ $order->created_at }}</td> <td>{{ $order->updated_at }}</td> <td> <a href="" class="btn btn-default">Скопировать</a></td> </tr> @endforeach </table> </div> </body> </html>
Тут ничего сложного нет. Перебираем массив $orders и выводим его значения. Единственное в ссылке «Скопировать» мы не указали адрес. Это мы сделаем чуть позже.
Осталось только добавить роут в файл routes/web.php
Route::get('/all', 'OrderController@index')->name('all');
Проверяем.
Отлично, все работает.
Теперь переходим к самому интересному. Создаем метод для копирования строки.
Создание метода копирования строки в Laravel
Создадим метод copy в контроллере OrderController и опишем его.
public function copy(Request $request) { $order = \App\Order::find($request->id); $newOrder = $order->replicate(); $newOrder->save(); return redirect()->back(); }
Первое мы получаем заказ по его id, используя метод find. Дальше используя метод replicate копируем данные и сохраняем их.
Отлично, теперь добавим роут.
Route::get('/copy/{id}', 'OrderController@copy')->name('copy');
Изменим немного файл index.blade.php. Добавим к ссылке адрес:
<a href="{{ route('copy',['id' => $order->id])}}" class="btn btn-default">Скопировать</a>
Теперь можно проверить. Напротив данных, жмем «Копировать» и у нас появляется новая запись с тем же именем.
Отлично. Все работает.
Заключение.
Для копирования данных из таблицы с помощью Eloquent в Laravel существует метод replicate(), который копирует данные.