Пример CRUD на Laravel 8 | Руководство по Laravel 8 для начинающих
В этой статье мы разберем, как создать функциональный CRUD-приложение с использованием Laravel 8. Вы узнаете, как работать с генераторами кода, правильно настроить маршруты с помощью Route Resource и обновлять данные в модели.
Мы пошагово покажем, как ускорить процесс разработки и избежать ошибок при реализации CRUD-операций. Это идеальный гид для начинающих, который поможет наладить быстрое создание и обновление записей в вашем проекте.
Шаг 1: Установите приложение Laravel 8
Для начала создайте новый проект в Laravel 8, добавив следующую команду в терминал.
composer create-project --prefer-dist laravel/laravel laravelblogШаг 2: Настройте базу данных MySQL
Теперь нужно создать базу данных MySQL и подключить эту базу данных к приложению Laravel. Откройте localhost/phpmyadmin и добавьте новое имя базы данных, затем добавьте учетные данные в файл .env, который отображается в корне вашего проекта.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravelblog #your_database_name
DB_USERNAME=root #your_database_username
DB_PASSWORD=admin #your_database_passwordТеперь вы сможете добавлять таблицы с помощью базы данных MySQL.
Шаг 3: Создайте модальное окно и миграцию
Теперь создайте модальное окно и миграцию, просто добавив в свой терминал указанную ниже команду, генерирующую модальное окно и миграцию, которая откроет вашу таблицу базы данных после запуска команды миграции.
php artisan make:model Post -mТеперь вы можете увидеть, что в папке migration в вашей базе данных создан новый файл, такой же, как показано ниже. Теперь вам нужно добавить в базу данных столбцы.
database\migrations\2020_09_13_071913_create_projects_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePostsTable extends Migration
{
/**
* Запускает миграции
*
* @return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title')->nullable();
$table->longText('description')->nullable();
$table->timestamps();
});
}
/**
* Переворачивает миграции
*
* @return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
}Теперь, когда вы добавили столбцы, запустите следующую команду, которая сгенерирует таблицу в вашей базе данных.
php artisan migrateДобавьте свойство fillable: Внутри вашего приложения/модального окна сгенерирован файл Post.php, в который вам нужно добавить свойства fillable.
app\Models\Post.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $fillable = [
'title', 'description'
];
}Шаг 4: Добавляем маршруты к источникам
В Laravel 8 в разделе маршрутов появились некоторые изменения: вам нужно использовать свой контроллер, а затем инициализировать класс контроллера. Откройте файл «routes / web.php» и укажите маршруты, как показано ниже.
routes/web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;
/*
|--------------------------------------------------------------------------
| Веб-Маршруты
|--------------------------------------------------------------------------
|
| Здесь вы можете зарегистрировать веб-маршруты для своего приложения.
| Эти маршруты загружаются провайдером RouteServiceProvider внутри |группы, которая содержит группу связующего программного обеспечения |"web". А теперь создайте что-нибудь замечательное!
|
*/
Route::resource('posts', PostController::class);
Route::get('/', function () {
return view('welcome');
});Шаг 5: Создайте контроллер
Теперь вам нужно создать контроллер, просто добавив указанную ниже команду, и сгенерировать новый контроллер ресурсов – PostController.
php artisan make:controller PostController --resourceПосле выполнения данной команды вы найдете новый файл по следующему пути: «app / Http / Controllers / PostController.php». Там вы увидите уже сформированные методы, такие как показано ниже. Теперь вам нужно добавить следующие коды в ваши функции:
1) index() => этот метод предоставляет вам все данные из базы данных.
2) create() => это метод для создания новой записи.
3) store() => этот метод хранит данные в вашей базе данных.
3) show() => этот метод показывает запись.
3) edit() => используя этот метод, мы можем отредактировать нашу запись.
3) update() => это метод для обновления записи.
7) destroy() => используя этот метод, мы можем удалить нашу запись.
Теперь откройте файл PostController.php и добавьте в него приведенный ниже код.
app/Http/Controllers/PostController.php
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
/**
* Отображает список ресурсов
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$posts = Post::all();
return view('posts.index', compact('posts'));
}
/**
* Выводит форму для создания нового ресурса
*
* @return \Illuminate\Http\Response
*/
public function create()
{
return view('posts.create');
}
/**
* Помещает созданный ресурс в хранилище
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$request->validate([
'title' => 'required',
'description' => 'required',
]);
Post::create($request->all());
return redirect()->route('posts.index')->with('success','Post created successfully.');
}
/**
* Отображает указанный ресурс.
*
* @param \App\Models\Post $post
* @return \Illuminate\Http\Response
*/
public function show(Post $post)
{
return view('posts.show',compact('post'));
}
/**
* Выводит форму для редактирования указанного ресурса
*
* @param \App\Models\Post $post
* @return \Illuminate\Http\Response
*/
public function edit(Post $post)
{
return view('posts.edit',compact('post'));
}
/**
* Обновляет указанный ресурс в хранилище
*
* @param \Illuminate\Http\Request $request
* @param \App\Models\Post $post
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Post $post)
{
$request->validate([
'title' => 'required',
'description' => 'required',
]);
$post->update($request->all());
return redirect()->route('posts.index')->with('success','Post updated successfully');
}
/**
* Удаляет указанный ресурс из хранилища
*
* @param \App\Models\Post $post
* @return \Illuminate\Http\Response
*/
public function destroy(Post $post)
{
$post->delete();
return redirect()->route('posts.index')
->with('success','post deleted successfully');
}
}Шаг 6: Создайте файлы blade
На этом этапе, мы создаем наши файлы просмотра. Для начала создайте две папки: первая – «макет», а вторая – «записи». В папке макета создайте файл app.blade.php, а внутри папки записей создайте ещё один файл blade. Если вы не знаете, как интегрировать наши blade-файлы в Laravel, то сначала прочитайте Как интегрировать шаблон Bootstrap в админ-панели Laravel. Теперь создайте следующие blade-файлы для вашего CRUD-приложения.
- layout.blade.php
- index.blade.php
- create.blade.php
- edit.blade.php
- show.blade.php
Теперь давайте создадим следующие файлы и вставим в них соответствующий код.
resources/views/layout/app.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Laravel 5.8 CRUD Example Tutorial</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/css/bootstrap.css" rel="stylesheet">
</head>
<body>
<div class="container">
@yield('content')
</div>
</body>
</html>resources/views/posts/index.blade.php
@extends('layout.app')
@section('content')
<div class="row">
<div class="col-lg-12 margin-tb">
<div class="pull-left">
<h2>Laravel 8 CRUD Example from scratch </h2>
</div>
<div class="pull-right">
<a class="btn btn-success" href="{{ route('posts.create') }}"> Create New Product</a>
</div>
</div>
</div>
@if ($message = Session::get('success'))
<div class="alert alert-success">
<p>{{ $message }}</p>
</div>
@endif
<table class="table table-bordered">
<tr>
<th>Title</th>
<th>Description</th>
</tr>
@foreach ($posts as $post)
<tr>
<td>{{ $post->title }}</td>
<td>{{ $post->description }}</td>
<td>
<a class="btn btn-info" href="{{ route('posts.show',$post->id) }}">Show</a>
<a class="btn btn-primary" href="{{ route('posts.edit',$post->id) }}">Edit</a>
<form action="{{ route('posts.destroy',$post->id) }}" method="POST">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
@endforeach
</table>
@endsectionresources/views/posts/create.blade.php
@extends('layout.app')
@section('content')
<div class="row">
<div class="col-lg-12 margin-tb">
<div class="pull-left">
<h2>Add New Post</h2>
</div>
<div class="pull-right">
<a class="btn btn-primary" href="{{ route('posts.index') }}"> Back</a>
</div>
</div>
</div>
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form action="{{ route('posts.store') }}" method="POST">
@csrf
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Name:</strong>
<input type="text" name="title" class="form-control" placeholder="Title">
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Description:</strong>
<textarea class="form-control" style="height:150px" name="description" placeholder="Description"></textarea>
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12 text-center">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</form>
@endsectionresources/views/posts/edit.blade.php
@extends('layout.app')
@section('content')
<div class="row">
<div class="col-lg-12 margin-tb">
<div class="pull-left">
<h2>Edit Post</h2>
</div>
<div class="pull-right">
<a class="btn btn-primary" href="{{ route('posts.index') }}"> Back</a>
</div>
</div>
</div>
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form action="{{ route('posts.update',$post->id) }}" method="POST">
@csrf
@method('PUT')
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Title:</strong>
<input type="text" name="title" value="{{ $post->title }}" class="form-control" placeholder="Title">
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Description:</strong>
<textarea class="form-control" style="height:150px" name="description" placeholder="Description">{{ $post->description }}</textarea>
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12 text-center">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</form>
@endsectionresources/views/posts/show.blade.php
@extends('layout.app')
@section('content')
<div class="row">
<div class="col-lg-12 margin-tb">
<div class="pull-left">
<h2> Show Post</h2>
</div>
<div class="pull-right">
<a class="btn btn-primary" href="{{ route('posts.index') }}"> Back</a>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Name:</strong>
{{ $post->title }}
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Description:</strong>
{{ $post->description }}
</div>
</div>
</div>
@endsectionНу, вот мы и подошли к концу нашего пошагового руководства по работе с CRUD в Laravel 8. В рассмотренном нами CRUD-приложении мы использовали одну функцию для создания и редактирования. Давайте запустим этот пример CRUD-приложения. Примените приведенную ниже команду и посмотрите в свой браузер.
php artisan serveТеперь вы можете открыть в своем браузере следующий URL-адрес: http: //localhost:8000/posts. Итак, друзья, это очень простой пошаговый способ работы с CRUD на фреймворке Laravel.
Надеюсь, это руководство поможет вам разобраться с CRUD на Laravel 8. Если у вас есть какие-либо вопросы относительно генератора операций CRUD на Laravel, пожалуйста, оставьте комментарий к этой статье, мы очень ценим ваше мнение.
Комментарии
Не очень понял, то есть строчка
Route::resource('posts', PostController::class);
автоматически подтягивает все маршруты,
которые прописаны в контроллере?
Например, в контроллере есть функция:
public function edit(Post $post)
{
return view('posts.edit',compact('post'));
}
Значит будет работать маршрут posts/edit?
То есть точка заменяется на слэш? И в
результате у нас общие имена для маршрута
и представления, которое лежит в
resources/views/posts/index.blade.php.
Всё верно?
Это ситуация из серии, когда строчек в коде
вроде стало меньше, но код от этого не стал
менее запутанным, скорее наоборот. По мне
так лучше больше строк, но где всё явно про-
писано, чтобы не гадать "как оно там внутри".
Вообще то, Ларавел работает с MVC (Model View Controller).
Route::resource('posts', [PostController::class])->name('post');
'post' - это адресная строка в браузере
PostController - сам контроллер в котором пишутся методы и вывод на шаблоны Blade
->name('post') - якорь ссылка на страницу в html. a href="{{ route('post') }}"
Изучите MVC - и Вам будет легче это всё понять.
Создание и удаление работают. Но при нажатии Show или Edit - ошибка ErrorException
compact(): Undefined variable: post
http://localhost:8000/posts/1
А вот так заработало:
public function show(Post $post)
{
// return view('posts.show',compact('posts'));
return view('posts.show', [ 'post' => $post, ]);
}
Ну так потому что надо писать return view('posts.show',compact('post')); так как переменной $posts не существует
Очень странно, тк compact($var) это сокращенная запись [ 'var' => $var ].
Спасибо за ваш комментарий, он может быть кому-то полезен.