讀取數(shù)據(jù)尝江,插入數(shù)據(jù)我們都學(xué)過了傲隶,還有一個(gè)非常重要的就是更新數(shù)據(jù)。
我們打開這個(gè)鏈接:http://localhost:8000/posts/2
下面我們要做兩件事:
- 我們要編輯這個(gè)評(píng)論胧瓜。
- 建立這個(gè)評(píng)論與用戶之間的關(guān)系矢棚,通常我們要知道是誰(shuí)發(fā)表了這個(gè)評(píng)論.
好,我們先來做編輯評(píng)論的這個(gè)功能府喳,簡(jiǎn)單的流程是我點(diǎn)擊這個(gè)評(píng)論蒲肋,跳轉(zhuǎn)到編輯評(píng)論的頁(yè)面,然后保存這個(gè)評(píng)論钝满。
我們先來想一下兜粘,顯示編輯評(píng)論的這個(gè)頁(yè)面的路由該怎么寫,通常是這樣表達(dá)的弯蚜,我要編輯某個(gè)帖子下的某個(gè)評(píng)論孔轴,那可能會(huì)這么寫:
// 編輯屬于帖子ID為3的評(píng)論ID為1的評(píng)論
// posts/3/comments/1/edit
posts/{post}/comments/{comment}/edit
嗯,上面的路由可以清晰的表達(dá)我們想要的意思碎捺,能很好的表達(dá)出具體功能的意思距糖,但是路徑太深了玄窝,我們簡(jiǎn)化下:
Route::get('comments/{comment}/edit', 'CommentsController@edit');
好的,我們到CommentsController
中寫上edit()
方法:
public function edit(Comment $comment)
{
// 加載視圖層悍引,并傳遞$comment數(shù)據(jù)到視圖
return view('comments.edit', compact('comment'));
}
然后恩脂,我們到pages/show.blade.php
中為我們的評(píng)論都加上一個(gè)編輯的鏈接:
<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>
下一步呢,當(dāng)然是建立我們的comments/edit.balde.php視圖層趣斤,路徑為resources/views/comments/edit.balde.php
@extends('layout')
@section('content')
<h1>Edit the Comment</h1>
<form method="{{-- 未知 --}}" action="{{-- 這里的路徑現(xiàn)在還沒寫 --}}">
{{ 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 點(diǎn)擊Edit,跳轉(zhuǎn)到http://localhost:8000/comments/11/edit頁(yè)面俩块,如下:
然后當(dāng)我們點(diǎn)擊Update Comment按鈕時(shí),這時(shí)候我們的路由該怎么寫浓领,對(duì)于將一條數(shù)據(jù)存入到數(shù)據(jù)庫(kù)玉凯,我們用post
方式,而對(duì)于更新一條數(shù)據(jù)联贩,我們應(yīng)該使用patch
或put
方式,我們來寫這個(gè)路由:
// 更新評(píng)論ID為X的評(píng)論
Route::patch('comments/{comment}', 'CommentsController@update');
進(jìn)入CommentsController編寫update()
方法:
public function update(Request $request, Comment $comment)
{
// update()只會(huì)更新Comment模型中$fillable允許的字段
$comment->update($request->all());
// 跳轉(zhuǎn)到該評(píng)論所屬的帖子頁(yè)
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
上面有一點(diǎn)要注意漫仆,我們現(xiàn)在是使用了PATCH
的請(qǐng)求,但是表單中的method只能識(shí)別get
和post
方法泪幌,所以對(duì)于patch, put, delete
這些方法盲厌,我們要這么寫:
<form method="POST" action="">
{{ method_field('PATCH') }}
</form>
當(dāng)然也可以直接這么寫:
<form method="POST" action="">
<input type="hidden" name="_method" value="PATCH">
</form>
我們的編輯評(píng)論的最簡(jiǎn)單的功能做完了,下面我們看下如何為評(píng)論添加用戶祸泪,我們先創(chuàng)建一個(gè)users
的migration文件吗浩,默認(rèn)安裝laravel的時(shí)候都是有這個(gè)文件的,我們最初把它刪除了没隘,現(xiàn)在再來創(chuàng)建一下:
php artisan make:migration create_users_table --create=users
編輯下這個(gè)文件的up()函數(shù):
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
這個(gè)migration文件中懂扼,添加user_id
外鍵:
$table->integer('user_id')->unsigned()->index();
現(xiàn)在如果我們直接執(zhí)行php artisan migrate
, users
表可以被創(chuàng)建,但是我們?cè)赾omments的migration文件中添加的user_id
外鍵是不會(huì)被創(chuàng)建的右蒲,對(duì)于這種添加一個(gè)字段阀湿,我們也要單獨(dú)寫一個(gè)migration文件。
不過在項(xiàng)目的初期瑰妄,我們也可以直接更改migration文件炕倘,然后執(zhí)行:
php artisan migrate:refresh
上面這條命令會(huì)清空所有的表并重新創(chuàng)建,需慎用, 如果只想撤銷上一次的migrate,可以使用php artisan migrate:rollback
命令翰撑,該命令會(huì)執(zhí)行migration文件中的down()
方法罩旋。
這里我們執(zhí)行下php artisan migrate:refresh
我們進(jìn)入tinker
, 重新插入一些數(shù)據(jù):
>>> 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,
}
我們?cè)俚?code>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
中寫上評(píng)論與用戶的關(guān)系
public function user()
{
return $this->belongsTo(User::class);
}
像上面這樣寫眶诈,程序跑通沒有問題涨醋,但是我們看{{ $comment->user->username }}
這條語(yǔ)句會(huì)在每次循環(huán)的時(shí)候都去查詢一次用戶表信息,導(dǎo)致數(shù)據(jù)庫(kù)的查詢次數(shù)過多逝撬,我們看一下:
如何解決這個(gè)問題呢浴骂,laravel提供了熱加載和懶加載的方式可以解決這個(gè)問題,我們進(jìn)入到
postsController
文件中宪潮,修改下show()
函數(shù):
public function show(Post $post)
{
$post = Post::with('comments.user')->find($post->id);
return view('posts.show', compact('post'));
}
我們看這句話Post::with('comments.user')
, 意思是查詢的時(shí)候加載post的關(guān)系comments, 而.user
是指加載comments
的關(guān)系時(shí)溯警,還需要加載comments的關(guān)系user
趣苏。 這樣就能解決多次查詢的問題了。
我們把上面的代碼優(yōu)化下梯轻,因?yàn)槲覀円呀?jīng)做了Post的路由模型綁定食磕,我們可以使用懶加載,所以代碼改成這樣:
public function show(Post $post)
{
$post->load('comments.user');
return view('posts.show', compact('post'));
}
在看下我們的語(yǔ)句查詢次數(shù):
關(guān)于熱加載和懶加載的具體區(qū)別喳挑,以后再說彬伦,大家現(xiàn)在可以不用區(qū)分的去使用它們。
好伊诵,本節(jié)到這里結(jié)束单绑。