10. 更新數(shù)據(jù)及渴求式加載Eager Loading - 從零開始學(xué)Laravel

從零學(xué)Laravel目錄列表

讀取數(shù)據(jù)尝江,插入數(shù)據(jù)我們都學(xué)過了傲隶,還有一個(gè)非常重要的就是更新數(shù)據(jù)。

我們打開這個(gè)鏈接:http://localhost:8000/posts/2

QQ20161121-0.png

下面我們要做兩件事:

  1. 我們要編輯這個(gè)評(píng)論胧瓜。
  2. 建立這個(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è)面俩块,如下:

編輯帖子頁(yè)

然后當(dāng)我們點(diǎn)擊Update Comment按鈕時(shí),這時(shí)候我們的路由該怎么寫浓领,對(duì)于將一條數(shù)據(jù)存入到數(shù)據(jù)庫(kù)玉凯,我們用post方式,而對(duì)于更新一條數(shù)據(jù)联贩,我們應(yīng)該使用patchput方式,我們來寫這個(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í)別getpost方法泪幌,所以對(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ù)過多逝撬,我們看一下:

數(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ù):


查詢次數(shù)

關(guān)于熱加載和懶加載的具體區(qū)別喳挑,以后再說彬伦,大家現(xiàn)在可以不用區(qū)分的去使用它們。

好伊诵,本節(jié)到這里結(jié)束单绑。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市曹宴,隨后出現(xiàn)的幾起案子搂橙,更是在濱河造成了極大的恐慌,老刑警劉巖笛坦,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件区转,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡弯屈,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門恋拷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來资厉,“玉大人,你說我怎么就攤上這事蔬顾⊙绯ィ” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵诀豁,是天一觀的道長(zhǎng)窄刘。 經(jīng)常有香客問我,道長(zhǎng)舷胜,這世上最難降的妖魔是什么娩践? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮烹骨,結(jié)果婚禮上翻伺,老公的妹妹穿的比我還像新娘。我一直安慰自己沮焕,他們只是感情好吨岭,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著峦树,像睡著了一般辣辫。 火紅的嫁衣襯著肌膚如雪旦事。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天急灭,我揣著相機(jī)與錄音姐浮,去河邊找鬼。 笑死化戳,一個(gè)胖子當(dāng)著我的面吹牛单料,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播点楼,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼扫尖,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了掠廓?” 一聲冷哼從身側(cè)響起换怖,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蟀瞧,沒想到半個(gè)月后沉颂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡悦污,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年铸屉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片切端。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡彻坛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出踏枣,到底是詐尸還是另有隱情昌屉,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布茵瀑,位于F島的核電站间驮,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏马昨。R本人自食惡果不足惜竞帽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鸿捧。 院中可真熱鬧抢呆,春花似錦、人聲如沸笛谦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)饥脑。三九已至恳邀,卻和暖如春懦冰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背谣沸。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工刷钢, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人乳附。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓内地,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親赋除。 傳聞我的和親對(duì)象是個(gè)殘疾皇子阱缓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容