读取数据,插入数据咱们都学过了,还有一个很是重要的就是更新数据。html
咱们打开这个连接:http://localhost:8000/posts/2laravel
下面咱们要作两件事:数据库
咱们要编辑这个评论。bash
创建这个评论与用户之间的关系,一般咱们要知道是谁发表了这个评论.函数
好,咱们先来作编辑评论的这个功能,简单的流程是我点击这个评论,跳转到编辑评论的页面,而后保存这个评论。post
咱们先来想一下,显示编辑评论的这个页面的路由该怎么写,一般是这样表达的,我要编辑某个帖子下的某个评论,那可能会这么写:优化
// 编辑属于帖子ID为3的评论ID为1的评论 // posts/3/comments/1/edit posts/{post}/comments/{comment}/edit
嗯,上面的路由能够清晰的表达咱们想要的意思,能很好的表达出具体功能的意思,可是路径太深了,咱们简化下:this
Route::get('comments/{comment}/edit', 'CommentsController@edit');
好的,咱们到CommentsController
中写上edit()
方法:spa
public function edit(Comment $comment) { // 加载视图层,并传递$comment数据到视图 return view('comments.edit', compact('comment')); }
而后,咱们到pages/show.blade.php
中为咱们的评论都加上一个编辑的连接:
<ul class="list-group"> @foreach ($post->comments as $comment) <li class="list-group-item"> {{ $comment->content }} <a href="/comments/{{ $comment->id }}/edit">Edit</a> </li> @endforeach </ul>
下一步呢,固然是创建咱们的comments/edit.balde.php视图层,路径为resources/views/comments/edit.balde.php
@extends('layout') @section('content') <h1>Edit the Comment</h1> <form method="{{-- 未知 --}}" action="{{-- 这里的路径如今还没写 --}}"> {{ csrf_field() }} <div class="form-group"> <textarea name="content" class="form-control">{{ $comment->content }}</textarea> </div> <div class="form-group"> <button type="submit" class="btn btn-primary">Update Comment</button> </div> </form> @stop
访问:http://localhost:8000/posts/2 点击Edit,跳转到http://localhost:8000/comment...页面,以下:
而后当咱们点击Update Comment按钮时,这时候咱们的路由该怎么写,对于将一条数据存入到数据库,咱们用post
方式,而对于更新一条数据,咱们应该使用patch
或put
方式,咱们来写这个路由:
// 更新评论ID为X的评论 Route::patch('comments/{comment}', 'CommentsController@update');
进入CommentsController编写update()
方法:
public function update(Request $request, Comment $comment) { // update()只会更新Comment模型中$fillable容许的字段 $comment->update($request->all()); // 跳转到该评论所属的帖子页 return redirect('posts/' . $comment->post->id); }
下面修改下视图:
@extends('layout') @section('content') <h1>Edit the Comment</h1> <form method="POST" action="/comments/{{ $comment->id }}"> {{ method_field('PATCH') }} {{ csrf_field() }} <div class="form-group"> <textarea name="content" class="form-control">{{ $comment->content }}</textarea> </div> <div class="form-group"> <button type="submit" class="btn btn-primary">Update Comment</button> </div> </form> @stop
上面有一点要注意,咱们如今是使用了PATCH
的请求,可是表单中的method只能识别get
和post
方法,因此对于patch, put, delete
这些方法,咱们要这么写:
<form method="POST" action=""> {{ method_field('PATCH') }} </form>
固然也能够直接这么写:
<form method="POST" action=""> <input type="hidden" name="_method" value="PATCH"> </form>
咱们的编辑评论的最简单的功能作完了,下面咱们看下如何为评论添加用户,咱们先建立一个users
的migration文件,默认安装laravel的时候都是有这个文件的,咱们最初把它删除了,如今再来建立一下:
php artisan make:migration create_users_table --create=users
编辑下这个文件的up()函数:
public function up() { Schema::create('users', function (Blueprint $table) { $table->increments('id'); $table->string('username')->unique(); $table->string('email')->unique(); $table->string('password'); $table->timestamps(); }); }
而后在create_comments_table.php
这个migration文件中,添加user_id
外键:
$table->integer('user_id')->unsigned()->index();
如今若是咱们直接执行php artisan migrate
, users
表能够被建立,可是咱们在comments的migration文件中添加的user_id
外键是不会被建立的,对于这种添加一个字段,咱们也要单独写一个migration文件。
不过在项目的初期,咱们也能够直接更改migration文件,而后执行:
php artisan migrate:refresh
上面这条命令会清空全部的表并从新建立,需慎用, 若是只想撤销上一次的migrate,可使用php artisan migrate:rollback
命令,该命令会执行migration文件中的down()
方法。
这里咱们执行下php artisan migrate:refresh
咱们进入tinker
, 从新插入一些数据:
>>> namespace App; => null >>> $user = New User; => App\User {#634} >>> $user->username = 'zhoujiping'; => "zhoujiping" >>> $user->email = 'zhoujiping@zhoujiping.com'; => "zhoujiping@zhoujiping.com" >>> $user->password = bcrypt('123456'); => "$2y$10$OM9pBb.xU58hvulnyhq1jeiWPxi8SbddYBW.rhhttEJMraBuVyWdq" >>> $user->save(); => true >>> $post = New Post; => App\Post {#627} >>> $post->title = 'My First Post'; => "My First Post" >>> $post->save(); => true >>> $comment = New Comment; => App\Comment {#639} >>> $comment->user_id = 1; => 1 >>> $comment->content = 'The content of the comment'; => "The content of the comment" >>> $post->addComment($comment); => App\Comment {#639 user_id: 1, content: "The content of the comment", post_id: 1, updated_at: "2016-11-21 06:02:33", created_at: "2016-11-21 06:02:33", id: 1, }
咱们再到pages/show.blade.php
视图,加上用户的用户名:
<ul class="list-group"> @foreach ($post->comments as $comment) <li class="list-group-item"> {{ $comment->content }} <a href="/comments/{{ $comment->id }}/edit">Edit</a> <a href="#" class="pull-right">{{ $comment->user->username }}</a> </li> @endforeach </ul>
不要忘记去Comment.php
中写上评论与用户的关系
public function user() { return $this->belongsTo(User::class); }
像上面这样写,程序跑通没有问题,可是咱们看{{ $comment->user->username }}
这条语句会在每次循环的时候都去查询一次用户表信息,致使数据库的查询次数过多,咱们看一下:
如何解决这个问题呢,laravel提供了热加载和懒加载的方式能够解决这个问题,咱们进入到postsController
文件中,修改下show()
函数:
public function show(Post $post) { $post = Post::with('comments.user')->find($post->id); return view('posts.show', compact('post')); }
咱们看这句话Post::with('comments.user')
, 意思是查询的时候加载post的关系comments, 而.user
是指加载comments
的关系时,还须要加载comments的关系user
。 这样就能解决屡次查询的问题了。
咱们把上面的代码优化下,由于咱们已经作了Post的路由模型绑定,咱们可使用懒加载,因此代码改为这样:
public function show(Post $post) { $post->load('comments.user'); return view('posts.show', compact('post')); }
在看下咱们的语句查询次数:
关于热加载和懒加载的具体区别,之后再说,你们如今能够不用区分的去使用它们。
好,本节到这里结束。