什么是crud应用_Laravel应用中的CRUD(创建读取更新删除)

什么是crud应用

If you would like to know more about Laravel, watch our Laravel live lesson with Isaac Castillo, teacher of our recent Laravel course.

如果您想了解有关Laravel的更多信息,请我们最近的Laravel课程的老师Isaac Castillo一起观看我们的Laravel现场课程。

In the previous part, we’ve bootstrapped our Laravel CRUD application by creating the database, some controllers, basic routes and simple views. In this part, we’ll wrap things up and implement proper CRUD.

在上一部分中,我们通过创建数据库,一些控制器,基本路由和简单视图来引导Laravel CRUD应用程序。 在这一部分中,我们将总结并实现适当的CRUD。

Laravel Logo

If you’d like to follow along through this interactive walk through Laravel’s docs, please catch up by reading the first part now.

如果您想通过Laravel的文档进行交互式互动,请立即阅读第一部分。

创建记录 (Creating A Record)

Continuing right where we left off, let’s create the page where we’ll actually perform this action. In our TasksController, let’s return a view like this:

在我们上次中断的地方继续,让我们创建一个页面,在该页面中我们将实际执行此操作。 在TasksController ,让我们返回如下视图:

public function create()
{
    return view('tasks.create');
}

And now, in our views directory, let’s create tasks/create.blade.php, and enter some starter content:

现在,在我们的views目录中,让我们创建tasks/create.blade.php ,并输入一些入门内容:

@extends('layouts.master')

@section('content')

<h1>Add a New Task</h1>
<p class="lead">Add to your task list below.</p>
<hr>

@stop

At this point, we could manually create a form, but Laravel offers a package to lighten this load for us – Illuminate/Html. Let’s pull that in quickly by running the following command:

在这一点上,我们可以手动创建一个表单,但是Laravel为我们减轻了负担,提供了一个软件包– Illuminate / Html 。 让我们通过运行以下命令快速将其拉入:

composer require illuminate/html

Now, inside our config/app.php file, let’s add the service provider to the list:

现在,在我们的config/app.php文件中,让我们将服务提供者添加到列表中:

'Illuminate\Html\HtmlServiceProvider',

Let’s add the aliases:

让我们添加别名:

'Form'      => 'Illuminate\Html\FormFacade',
'Html'      => 'Illuminate\Html\HtmlFacade',

We can now easily create a form in our create.blade.php file. Let’s go ahead and do that using the form facade and blade syntax:

现在,我们可以轻松地在create.blade.php文件中创建一个表单。 让我们继续使用窗体facade和blade语法进行操作:

{!! Form::open([
    'route' => 'tasks.store'
]) !!}

<div class="form-group">
    {!! Form::label('title', 'Title:', ['class' => 'control-label']) !!}
    {!! Form::text('title', null, ['class' => 'form-control']) !!}
</div>

<div class="form-group">
    {!! Form::label('description', 'Description:', ['class' => 'control-label']) !!}
    {!! Form::textarea('description', null, ['class' => 'form-control']) !!}
</div>

{!! Form::submit('Create New Task', ['class' => 'btn btn-primary']) !!}

{!! Form::close() !!}

Check out this screenshot of our create view so far.

查看到目前为止我们create视图的屏幕截图。

Create view default

One important thing to note here is that I’ve specified the route on which we will POST to, according to our resourceful routes list. We’ll use the store method to process the data, so let’s head back to our TasksController, and start processing that data.

这里要注意的一件事是,根据资源丰富的路由列表,我已经指定了要发布到的路由。 我们将使用store方法来处理数据,因此让我们回到TasksController ,开始处理该数据。

Let’s turn our heads to requests in Laravel.

让我们转向Laravel中的请求

The Request facade will grant you access to the current request that is bound in the container.

Request外观将授予您访问绑定在容器中的当前请求的权限。

We can obtain our request instance in two ways, according to the documentation. Let’s stick with the dependency injection method. Our store method should now look like this:

根据文档,我们可以通过两种方式获取请求实例。 让我们坚持依赖注入方法。 现在,我们的store方法应如下所示:

public function store(Request $request)
{
    //
}

Now, we can dump out the information to see what gets posted. We’ll use the helper function, dd(), which is included by default in Laravel. It combines Symphony’s VarDupmer component, and the PHP die function. Add the following to the store method:

现在,我们可以转储信息以查看发布的内容。 我们将使用辅助函数dd() ,该函数默认包含在Laravel中。 它结合了Symphony的VarDupmer组件和PHP die函数。 将以下内容添加到store方法中:

dd($request->all());

Now submit the empty form, and you’ll see the data. Go back and fill in some dummy data in the form, and you’ll see the request updated. If we’re not interested in any validation, then saving the new task to the database is easy. In the docs for Eloquent, we’ll notice that we can call the create method to create a new row in our table. Let’s do that by adding the following to our store method. We’ll also redirect back to where we came from:

现在提交空白表格,您将看到数据。 返回并在表单中填写一些虚拟数据,您将看到请求已更新。 如果我们对任何验证都不感兴趣,那么将新任务保存到数据库很容易。 在Eloquent的文档中,我们会注意到我们可以调用create方法在表中创建新行。 通过将以下内容添加到我们的store方法中来进行操作。 我们还将重定向回到我们的来源:

public function store(Request $request)
{
    $input = $request->all();

    Task::create($input);

    return redirect()->back();
}

We’re ready to create a new task now. Let’s go ahead and enter some dummy data and submit it. Uh oh… there’s a MassAssignmentException. Laravel by default prevents mass assignment, which is a good thing. This just means that we have to declare which fields are mass-assignable. I suggest you read up on this, but here’s what our updated Task model will look like:

我们现在准备创建一个新任务。 让我们继续,输入一些虚拟数据并提交。 哦,哦……有一个MassAssignmentException 。 Laravel默认情况下阻止批量分配,这是一件好事。 这仅意味着我们必须声明哪些字段可大量分配。 我建议您仔细阅读 ,但这是我们更新后的Task模型的外观:

class Task extends Model {

    /**
     * Fillable fields
     * 
     * @var array
     */
    protected $fillable = [
        'title',
        'description'
    ];

}

Now, let’s try to add our task again. If we were successful, we should be redirected back to where we came from, i.e. the “create task” page. There’s no indication right now as to whether the task was successfully added, but let’s check the database through the command line:

现在,让我们尝试再次添加任务。 如果我们成功了,我们应该被重定向我们的来源,即“创建任务”页面。 现在尚无关于任务是否已成功添加的指示,但让我们通过命令行检查数据库:

sqlite3 storage/database.sqlite
select * from tasks;

We should see the table returned with our new entry. Sweet! What about success messages and validation? Let’s first validate our input, to make sure all fields are required. Laravel ships with a really easy-to-use Validator class, and a quick read should have us going in no time. We’re validating in our controller, so let’s look at that section. Let’s validate our input by adding this to the beginning of the store method:

我们应该看到该表随我们的新条目一起返回。 甜! 关于成功消息和验证呢? 让我们首先验证输入,以确保所有字段都是必需的。 Laravel附带了一个非常易于使用的Validator类 ,并且快速阅读就可以让我们立即行动。 我们正在控制器中进行验证,因此让我们看一下该部分 。 让我们通过将其添加到store方法的开头来验证输入:

$this->validate($request, [
    'title' => 'required',
    'description' => 'required'
]);

Notice now that if we leave out any of our input, the rest of our method doesn’t execute, and we remain on the page with whatever input has already been entered. Laravel will automatically throw an error, which we can access in our blade template. Let’s insert the following snippet above our form:

现在请注意,如果我们遗漏了任何输入,则该方法的其余部分将不会执行,并且无论输入什么内容,我们都会保留在页面上。 Laravel将自动引发错误,我们可以在刀片模板中访问该错误。 让我们在表单上方插入以下代码段:

@if($errors->any())
    <div class="alert alert-danger">
        @foreach($errors->all() as $error)
            <p>{{ $error }}</p>
        @endforeach
    </div>
@endif

Now, we’ll see the errors neatly written out for us.

现在,我们将看到为我们精心编写的错误。

Create task errors

What about a success message? Well, if our validator passes, the rest of our code will execute, and we can redirect back with a Session flash message. Update the store method to create a new flash message:

那成功消息呢? 好吧,如果我们的验证程序通过,我们的其余代码将执行,我们可以使用Session flash message重定向回去。 更新store方法以创建新的Flash消息:

public function store(Request $request)
{
    $this->validate($request, [
        'title' => 'required',
        'description' => 'required'
    ]);

    $input = $request->all();

    Task::create($input);

    Session::flash('flash_message', 'Task successfully added!');

    return redirect()->back();
}

Now, we can add this to our blade template:

现在,我们可以将其添加到刀片模板中:

@if(Session::has('flash_message'))
    <div class="alert alert-success">
        {{ Session::get('flash_message') }}
    </div>
@endif

Here’s what we should see.

这是我们应该看到的。

Create success message

We’re now validating and adding tasks, as well as passing data back to the view for output. Excellent. We still need a way to actually see our records.

现在,我们正在验证和添加任务,以及将数据传递回视图以进行输出。 优秀的。 我们仍然需要一种方法来实际查看我们的记录。

阅读记录 (Reading Records)

Back in our index method, we can now output all tasks that we’ve created so far. Add this to the index method:

回到index方法,我们现在可以输出到目前为止已经创建的所有任务。 将此添加到index方法:

public function index()
{
    $tasks = Task::all();

    return view('tasks.index')->withTasks($tasks);
}

We can access and output the tasks like this:

我们可以访问和输出如下任务:

@foreach($tasks as $task)
    <h3>{{ $task->title }}</h3>
    <p>{{ $task->description}}</p>
    <p>
        <a href="{{ route('tasks.show', $task->id) }}" class="btn btn-info">View Task</a>
        <a href="{{ route('tasks.edit', $task->id) }}" class="btn btn-primary">Edit Task</a>
    </p>
    <hr>
@endforeach

Here’s a screenshot for the index view.

这是索引视图的屏幕截图。

Task listing

Let us now figure out how we’re going to display a single record. In this current app, it’s probably not necessary because we’re already outputting all the information, but we’ll do it anyway. If we look at our routes list, it’s apparent that the tasks.show route is the way to go. It accepts a wildcard in the URL, and for our app, we’ll use the ID of the task. As before, we’ll create a show.blade.php file and extend our master layout:

现在让我们弄清楚如何显示一条记录。 在此当前应用中,可能没有必要,因为我们已经输出了所有信息,但是无论如何我们都会这样做。 如果我们查看路线列表,很显然, tasks.show route是tasks.show的方式。 它在URL中接受通配符,对于我们的应用程序,我们将使用任务的ID。 和以前一样,我们将创建一个show.blade.php文件并扩展主布局:

@extends('layouts.master')

@section('content')

<h1>{{ $task->title }}</h1>
<p class="lead">{{ $task->description }}</p>
<hr>

<a href="{{ route('tasks.index') }}" class="btn btn-info">Back to all tasks</a>
<a href="{{ route('tasks.edit', $task->id) }}" class="btn btn-primary">Edit Task</a>

<div class="pull-right">
    <a href="#" class="btn btn-danger">Delete this task</a>
</div>

@stop

Now, let’s update our show method:

现在,让我们更新show方法:

public function show($id)
{
    return view('tasks.show');
}

If we navigate to a URL with a random wildcard – /tasks/320918 – we should see our dummy template. Let’s actually fetch the correct task. Using Eloquent, we can search for a record with the matching ID, and if none are found, we’ll throw a ModelNotFoundException which we can catch. If the record is found, we can access it in our view. Here’s the updated method:

如果导航到带有随机通配符的/tasks/320918我们应该看到我们的虚拟模板。 让我们实际获取正确的任务。 使用Eloquent,我们可以搜索具有匹配ID的记录,如果找不到匹配的记录,则将抛出ModelNotFoundException可以捕获。 如果找到了记录,我们可以在视图中访问它。 这是更新的方法:

public function show($id)
{
    $task = Task::findOrFail($id);

    return view('tasks.show')->withTask($task);
}

Now in our view, we can output the record properly like this:

现在,在我们看来,我们可以像这样正确地输出记录:

<h1>{{ $task->title }}</h1>
<p class="lead">{{ $task->description }}</p>

Navigate to tasks/1, and you should see the output.

导航到tasks/1 ,您应该看到输出。

Single task view

Back in our index view, we can now output the links to each individual task:

回到index视图,我们现在可以输出指向每个任务的链接:

<a href="{{ route('tasks.show', $task->id) }}">view</a>

Notice that we passed in the correct wildcard based on the task ID. You should now be able to click through nicely! Let’s move on to editing.

请注意,我们根据任务ID传递了正确的通配符。 现在,您应该可以很好地点击了! 让我们继续进行编辑。

使用表单模型绑定更新记录 (Updating A Record Using Form-Model Binding)

By now, you probably realize how easy it is to get a new view ready for our RESTful app. It’s no different this time, so we’ll create the edit.blade.php file, pull in the master layout, and link the corresponding controller method to it. Here’s the edit method:

到目前为止,您可能已经意识到为我们的RESTful应用准备好新视图是多么容易。 这次没有什么不同,因此我们将创建edit.blade.php文件,获取主布局,并将相应的控制器方法链接到该文件。 这是edit方法:

public function edit($id)
{
    return view('tasks.edit');
}

And here’s the view to match:

这是匹配的视图:

@extends('layouts.master')

@section('content')

<h1>Edit Task - Task Name </h1>
<p class="lead">Edit this task below. <a href="{{ route('tasks.index') }}">Go back to all tasks.</a></p>
<hr>

@stop

If you look at the routes list, you’ll notice that the edit route also accepts a wildcard. We’ll be consistent and use the ID. Navigating to /tasks/gibberish/edit will display the dummy page, but let’s pull in the proper content. First of all, we can update all our “edit” links on the index and show views like this:

如果查看路线列表,您会注意到编辑路线也接受通配符。 我们将保持一致并使用ID。 导航到/tasks/gibberish/edit将显示虚拟页面,但让我们输入适当的内容。 首先,我们可以更新index上的所有“编辑”链接,并show视图:

<a href="{{ route('tasks.edit', $task->id) }}">edit</a>

Notice again how we’re calling the correct route and passing in the corresponding wildcard. In our edit template, we’re going to want a similar form to the one we used to create a task, but it would be pretty useful if the form was already populated with the existing fields. Thanks to Laravel’s form-model binding, this is a piece of cake. We’ll copy over the create form, although a better practice would be to extract this to a partial of some sort. In any case, we’ll copy it over, and bind our model to it:

再次注意我们如何调用正确的路由并传递相应的通配符。 在我们的编辑模板中,我们想要一个与用于创建任务的表单类似的表单,但是如果该表单已经用现有字段填充,那将非常有用。 感谢Laravel的表单模型绑定,这真是小菜一碟。 我们将复制创建表单,尽管更好的做法是将其提取为某种形式。 无论如何,我们都将其复制,然后将模型绑定到该模型:

{!! Form::model($task, [
    'method' => 'PATCH',
    'route' => ['tasks.update', $task->id]
]) !!}

<div class="form-group">
    {!! Form::label('title', 'Title:', ['class' => 'control-label']) !!}
    {!! Form::text('title', null, ['class' => 'form-control']) !!}
</div>

<div class="form-group">
    {!! Form::label('description', 'Description:', ['class' => 'control-label']) !!}
    {!! Form::textarea('description', null, ['class' => 'form-control']) !!}
</div>

{!! Form::submit('Update Task', ['class' => 'btn btn-primary']) !!}

{!! Form::close() !!}

Notice how we’re using a PATCH request in the form to stay in line with our RESTful resource. Notice also how we are calling on the variable $task, binding it to the model, and referencing the ID which will be used to look up the table. This means that we have to pass in the correct task. In the TasksController, we can update the edit method to this:

请注意,我们如何在表单中使用PATCH请求以与RESTful资源保持一致。 还请注意,我们如何调用变量$task ,将其绑定到模型,并引用将用于查找表的ID。 这意味着我们必须传递正确的任务。 在TasksController ,我们可以将edit方法更新为:

public function edit($id)
{
    $task = Task::findOrFail($id);

    return view('tasks.edit')->withTask($task);
}

Just like before, if an ID isn’t found, we’ll get the ModelNotFoundException. We can, at this point, copy over our errors snippet again, but this isn’t very DRY at all. Don’t worry, we can fix that easily by leveraging partials. Blade allows us to reference any file by using the @include() directive. First, let’s create a folder in our views directory called partials. In there, I’ll create a sub-directory called alerts, and then a file called errors.blade.php. Let’s copy over our errors snippet into this new file:

和以前一样,如果没有找到ID,我们将获得ModelNotFoundException 。 此时,我们可以再次复制错误代码段,但这根本不是很干燥。 不用担心,我们可以通过利用局部函数轻松地解决此问题。 Blade允许我们使用@include()指令来引用任何文件。 首先,让我们在views目录中创建一个名为partials的文件夹。 在那里,我会创建一个名为的子目录alerts ,然后一个名为errors.blade.php 。 让我们将错误代码片段复制到这个新文件中:

@if($errors->any())
    <div class="alert alert-danger">
        @foreach($errors->all() as $error)
            <p>{{ $error }}</p>
        @endforeach
    </div>
@endif

Now, we can reference it in any of our files like this:

现在,我们可以在我们的任何文件中引用它,如下所示:

@include('partials.alerts.errors')

We can now replace the original snippet in our create.blade.php template with this partial reference, and reference it in our edit template as well. The whole edit view should look like this now:

现在,我们可以使用此部分引用替换create.blade.php模板中的原始代码段,并在我们的编辑模板中对其进行引用。 现在,整个编辑视图应如下所示:

@extends('layouts.master')

@section('content')

<h1>Editing "{{ $task->title }}"</h1>
<p class="lead">Edit and save this task below, or <a href="{{ route('tasks.index') }}">go back to all tasks.</a></p>
<hr>

@include('partials.alerts.errors')

@if(Session::has('flash_message'))
    <div class="alert alert-success">
        {{ Session::get('flash_message') }}
    </div>
@endif

{!! Form::model($task, [
    'method' => 'PATCH',
    'route' => ['tasks.update', $task->id]
]) !!}

<div class="form-group">
    {!! Form::label('title', 'Title:', ['class' => 'control-label']) !!}
    {!! Form::text('title', null, ['class' => 'form-control']) !!}
</div>

<div class="form-group">
    {!! Form::label('description', 'Description:', ['class' => 'control-label']) !!}
    {!! Form::textarea('description', null, ['class' => 'form-control']) !!}
</div>

{!! Form::submit('Update Task', ['class' => 'btn btn-primary']) !!}

{!! Form::close() !!}

@stop

Here’s a screenshot of the view when we’re editing a task.

这是我们编辑任务时视图的屏幕截图。

Editing a task

Let’s jump into our update method now, which will receive the data from the form submission, and try to update our record. Like before, we’ll validate our input, and log the errors in our view if any exist. If validation passes, we’ll grab the input, update the task, save it, and redirect back with a success message. Here’s what the method looks like:

现在让我们进入update方法,该方法将从表单提交中接收数据,并尝试更新记录。 和以前一样,我们将验证输入,并在视图中记录错误(如果存在)。 如果验证通过,我们将获取输入,更新任务,保存任务,然后重定向并返回一条成功消息。 该方法如下所示:

public function update($id, Request $request)
{
    $task = Task::findOrFail($id);

    $this->validate($request, [
        'title' => 'required',
        'description' => 'required'
    ]);

    $input = $request->all();

    $task->fill($input)->save();

    Session::flash('flash_message', 'Task successfully added!');

    return redirect()->back();
}

Try it out and see for yourself, it works! You can now create, read, and update records, but let’s cross the final hurdle.

试试看,亲自体验一下,行之有效! 您现在可以创建,读取和更新记录,但让我们越过最后的障碍。

删除记录 (Deleting A Record)

Deleting a record RESTfully actually requires a DELETE request. You can get around this outside the controller with JavaScript, but that’s a bit beyond the scope of this article. If we view a single task, you’ll notice that I left a placeholder button there to delete it. We actually need to change this into a form that sends a DELETE request to the destroy method, and handle the record deletion there. Here’s our updated show template incorporating the delete form:

RESTful删除记录实际上需要DELETE请求。 您可以使用JavaScript在控制器之外解决此问题,但这超出了本文的范围。 如果我们查看单个任务,您会注意到我在那里留下了一个占位符按钮以将其删除。 实际上,我们实际上需要将其更改为一种形式,该形式将DELETE请求发送到destroy方法,并在那里处理记录删除。 这是我们结合了删除表单的更新后的显示模板:

@extends('layouts.master')

@section('content')

<h1>{{ $task->title }}</h1>
<p class="lead">{{ $task->description }}</p>
<hr>

<div class="row">
    <div class="col-md-6">
        <a href="{{ route('tasks.index') }}" class="btn btn-info">Back to all tasks</a>
        <a href="{{ route('tasks.edit', $task->id) }}" class="btn btn-primary">Edit Task</a>
    </div>
    <div class="col-md-6 text-right">
        {!! Form::open([
            'method' => 'DELETE',
            'route' => ['tasks.destroy', $task->id]
        ]) !!}
            {!! Form::submit('Delete this task?', ['class' => 'btn btn-danger']) !!}
        {!! Form::close() !!}
    </div>
</div>

@stop

Inside our TaskController, we can handle the request in the destroy method, rounding off our RESTful controller. Once again, Eloquent makes this a breeze. We’ll fetch the associated record in the table, delete it, and redirect back to the task list:

TaskController ,我们可以使用destroy方法处理请求,从而完善RESTful控制器。 雄辩的雄辩再次使这变得轻而易举。 我们将获取表中的关联记录,将其删除,然后重定向回任务列表:

public function destroy($id)
{
    $task = Task::findOrFail($id);

    $task->delete();

    Session::flash('flash_message', 'Task successfully deleted!');

    return redirect()->route('tasks.index');
}

At this point, let’s refactor our flash message into the master layout file so that it shows up on every template whenever a flash message is posted. We can remove it from the create and edit templates, and keep it only in the master layout like this:

此时,让我们将Flash消息重构为主布局文件,以便每当发布Flash消息时,它就会显示在每个模板上。 我们可以将其从创建和编辑模板中删除,并仅将其保留在主布局中,如下所示:

<main>
    <div class="container">
        @if(Session::has('flash_message'))
            <div class="alert alert-success">
                {{ Session::get('flash_message') }}
            </div>
        @endif
        
        @yield('content')
    </div>
</main>

Now, navigate to a task, and delete it. You’ll be redirected back to the task list with a flash message informing you that the task has successfully been deleted. Of course, your task list will be updated to match.

现在,导航至任务,然后将其删除。 您将通过一条简短的消息重定向到任务列表,通知您任务已成功删除。 当然,您的任务列表将被更新以匹配。

结语 (Wrapping Up)

We’ve tapped into a lot of core concepts in this tutorial, and touched on a lot of neat Laravel functionality. By building up this CRUD application from scratch, we’ve gotten our taste buds wet with the Laravel workflow.

在本教程中,我们利用了许多核心概念,并介绍了许多简洁的Laravel功能。 通过从头开始构建此CRUD应用程序,我们可以通过Laravel工作流程来解决我们的味蕾。

You should have a solid base and understanding to go on and build something yourself. I highly recommend checking out the various parts of the documentation to see what’s available, and just experimenting around as well. Use this as a building block, and get out there and show off your artisanal spirit. Feedback? Comments? Leave them below!

您应该具有扎实的基础和理解才能继续自己构建一些东西。 我强烈建议您查看文档的各个部分,以了解可用的内容,并且也要进行实验。 用它作为构建基块,然后走到那里,炫耀您的手工精神。 反馈? 注释? 把它们留在下面!

Continue learning about Laravel with our Laravel live lesson. One teacher, one lesson, followed by your Laravel questions.

通过我们的Laravel现场课程,继续学习Laravel。 一位老师,一堂课,然后是您的Laravel问题。

翻译自: https://www.sitepoint.com/crud-create-read-update-delete-laravel-app/

什么是crud应用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值