Laravel教程 十:实现文章的修改

JellyBool

JellyBool

我们之前的一系列文章综合起来就实现了一个发布文章的整个流程,但是万一我们需要修改某篇文章的内容呢?我们该如何去实现呢?其实,有了怎么创建一篇文章之后,我们实现编辑(更新)文章的思路很类似。这里可以值得注意的知识点就是Form::modelgetAttribute了。来看看具体的步骤:

注册路由

routes.php中,注册我们的编辑页面的路由:

Route::get('article/edit/{id}','ArticleController@edit');

这个路由接受一个参数:id,意为文章的id,我们会需要根据这个id来查询我们要修改的文章。

编写edit方法

根据路由,我们在ArticleController添加edit()方法:

public function edit($id)
    {
        $article = Article::findOrFail($id);
        $tags = Tag::lists('name', 'id');
        return view('articles.edit',compact('article','tags'));
    }

很熟悉地,我们首先根据id来查询到我们需要编辑的文章,对于$tags,我们采取跟create()方法一样的方法,得到我们的$tags列表。然后渲染视图,并将查询到的$article$tags传给视图。

创建视图

上面的edit()方法指定了渲染articles.edit(resources/views/articles/edit.blade.php)这个视图,我们来创建之,这里为了便利,我们可以直接将create.blade.php这个视图文件拷贝过来:

@extends('app')
@section('content')
    <h1>修改文章:{{ $article->title }}</h1>
    {!! Form::model($article,['url'=>'article/update']) !!}
    {!! Form::hidden('id',$article->id) !!}
    <div class="form-group">
        {!! Form::label('title','标题:') !!}
        {!! Form::text('title',$article->title,['class'=>'form-control']) !!}
    </div>
    <div class="form-group">
        {!! Form::label('content','正文:') !!}
        {!! Form::textarea('content',$article->content,['class'=>'form-control']) !!}
    </div>
    <div class="form-group">
        {!! Form::label('published_at','发布日期') !!}
        {!! Form::input('date','published_at',$article->published_at->format('Y-m-d'),['class'=>'form-control']) !!}
    </div>
    <div class="form-group">
        {!! Form::label('tag_list','选择标签') !!}
        {!! Form::select('tag_list[]',$tags,null,['class'=>'form-control js-example-basic-multiple','multiple'=>'multiple']) !!}
    </div>
    <div class="form-group">
        {!! Form::submit('修改文章',['class'=>'btn btn-success form-control']) !!}
    </div>
    {!! Form::close() !!}
    @if($errors->any())
        <ul class="alert alert-danger">
            @foreach($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    @endif
    <script type="text/javascript">
        $(function() {
            $(".js-example-basic-multiple").select2({
                placeholder: "添加标签"
            });
        });
    </script>
@endsection

这里我们注意下面这几点:

我们使用了Form::hidden()

这里我们使用这个目的(因为hidden表单并不会展示给用户看)就是为了后面在更新的时候更加便捷和暴力,因为有了id,我们一切的事情都很好办。

我们给Form input表单设置了初始值

通过类似{!! Form::text('title',$article->title,['class'=>'form-control']) !!}中的$article->title的形式,我们给表单赋予了初始值。

我们使用了Form::model()

在声明Form的时候,我们并不是简单的使用Form::open(),Form::model()首先需要将你要绑定的model传进来,这里我们用的是$article,也就是我们在edit()方法查找到的$article,这个有什么好处呢?

一旦绑定Form::model(),在后面的input表单中即使你没有设置初始值,laravel也会自动为你匹配,然后
为你赋予初始值,这也是使用Form的好处之一,就比如上面的{!! Form::text('title',$article->title,['class'=>'form-control']) !!},在Form::model()下,你完全可以像之前那样写:

{!! Form::text('title',null,['class'=>'form-control']) !!}

你依然会得到相同的效果,但是这里为了更清晰,我直接赋了$article->title初始值。

我们又使用Carbon

在文章的published_at这个字段,我们借$article->published_at->format('Y-m-d')又一次感受到了Carbon的便利。

最后来看看我们的编辑页面有没有好:

替代文字

仔细看其实就会发现,这样还没有完全实现编辑,因为我们的标签还没有同步过来,我们看到的标签select都是空的,但是原来的文章是有标签的啊,这个怎么办呢?

getAttribute

getAttribute就可以登场了,借助tag_list[]这个便利特性,我们可以在Article.php中为其设置一个getAttribute方法:

 public function getTagListAttribute()
    {
        // laravel 5.1 needs all()
        return $this->tags->lists('id')->all();
        // tags means tags() many-to-many relationship with tag
    }

这里需要说明一下,类似getAttribute都统一使用驼峰法。然后取值的时候就统一使用下划线的方法,比如这里的tag_list就是对应TagList,如果你写成tag_involved,方法就是getTagInvolvedAttribute()。这样写laravel会自动获取这个值。

注意,laravel 5.0版本,写成这样return $this->tags->lists('id');

我们来看看效果:

替代文字

OK,这里我们实现完编辑页面之后,我们根据Form::model()url来注册一个post路由

注册post路由

来到routes.php中,为update方法增加post路由:

Route::post('article/update','ArticleController@update');

修改文章的表单会提交到article/update,然后触发ArticleControllerupdate()方法。

编写update()

ArticleController中增加update()方法:

public function update(Requests\StoreArticleRequest $request)
    {
        //这里使用同样地验证规则
       dd($request->all());
    }

我们来看看有没有拿到提交过来的数据:

替代文字

OK,我们争取拿到数据了,接下来就是实现更新了。修改我们的update()方法:

public function update(Requests\StoreArticleRequest $request)
    {
        //根据id查询到需要更新的article
        $article = Article::find($request->get('id'));
        //使用Eloquent的update()方法来更新,
        //request的except()是排除某个提交过来的数据,我们这里排除id
        $article->update($request->except('id'));
        // 跟attach()类似,我们这里使用sync()来同步我们的标签
        $article->tags()->sync($request->get('tag_list'));
        
        return redirect('/');
    }

OK,代码逻辑实现完了之后,我们来看看是否能更新成功:

替代文字

Bang,大工告成!!

总结

如果你一直都跟着教程来,这个修改文章的过程应该思路很清晰。我们在这里再一次感受到:

注册路由--->控制器写方法--->加载视图

这一个神奇的轮回。这里还是需要强调的是Form::model()getAttribute这两个知识点。

最后,到这里,貌似我们的整个教程就可以结束了。下面我打算再开一个系列说说laravel 5.1的新特性.

Happy Hacking

本文由 JellyBool 创作, 转载和引用遵循 署名-非商业性使用 2.5 中国大陆 进行许可。

共有 92 条评论

openwrtmail
修改的评论也不能少于六个字哦!
JellyBool
修改的评论也不能少于六个字哦!
openwrtmail
修改的评论也不能少于六个字哦!
JellyBool
修改的评论也不能少于六个字哦!
openwrtmail
修改的评论也不能少于六个字哦!
JellyBool
修改的评论也不能少于六个字哦!
openwrtmail
修改的评论也不能少于六个字哦!
JellyBool
修改的评论也不能少于六个字哦!
Kirits
修改的评论也不能少于六个字哦!
Kirits
修改的评论也不能少于六个字哦!
JellyBool
修改的评论也不能少于六个字哦!
Dickson
修改的评论也不能少于六个字哦!
JellyBool
修改的评论也不能少于六个字哦!
JellyBool
修改的评论也不能少于六个字哦!
Kirits
修改的评论也不能少于六个字哦!
JellyBool
修改的评论也不能少于六个字哦!
JellyBool
修改的评论也不能少于六个字哦!
Kirits
修改的评论也不能少于六个字哦!
JellyBool
修改的评论也不能少于六个字哦!
Kirits
修改的评论也不能少于六个字哦!
Kirits
修改的评论也不能少于六个字哦!
JellyBool
修改的评论也不能少于六个字哦!
taruca
修改的评论也不能少于六个字哦!
JellyBool
修改的评论也不能少于六个字哦!
xiaohan
修改的评论也不能少于六个字哦!
JellyBool
修改的评论也不能少于六个字哦!
xiaohan
修改的评论也不能少于六个字哦!
Sky
修改的评论也不能少于六个字哦!
lanhuan
修改的评论也不能少于六个字哦!
xueyunlong67
修改的评论也不能少于六个字哦!
xueyunlong67
修改的评论也不能少于六个字哦!
JellyBool
修改的评论也不能少于六个字哦!
xueyunlong67
修改的评论也不能少于六个字哦!
nescafe
修改的评论也不能少于六个字哦!
JellyBool
修改的评论也不能少于六个字哦!
JellyBool
修改的评论也不能少于六个字哦!
xueyunlong67
修改的评论也不能少于六个字哦!
JellyBool
修改的评论也不能少于六个字哦!
xueyunlong67
修改的评论也不能少于六个字哦!
JellyBool
修改的评论也不能少于六个字哦!
xueyunlong67
修改的评论也不能少于六个字哦!
Smile
修改的评论也不能少于六个字哦!
JellyBool
修改的评论也不能少于六个字哦!
Smile
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
Anonymous
修改的评论也不能少于六个字哦!
indigolove
修改的评论也不能少于六个字哦!
JellyBool 回复 indigolove
修改的评论也不能少于六个字哦!
wangtaihong
修改的评论也不能少于六个字哦!
hybridword
修改的评论也不能少于六个字哦!
JellyBool 回复 hybridword
修改的评论也不能少于六个字哦!
hybridword 回复 JellyBool
修改的评论也不能少于六个字哦!
JellyBool 回复 hybridword
修改的评论也不能少于六个字哦!
hybridword 回复 JellyBool
修改的评论也不能少于六个字哦!
JellyBool 回复 hybridword
修改的评论也不能少于六个字哦!
hybridword 回复 JellyBool
修改的评论也不能少于六个字哦!
JellyBool 回复 hybridword
修改的评论也不能少于六个字哦!
hybridword 回复 JellyBool
修改的评论也不能少于六个字哦!
JellyBool 回复 hybridword
修改的评论也不能少于六个字哦!
hybridword 回复 JellyBool
修改的评论也不能少于六个字哦!
bluescheung
修改的评论也不能少于六个字哦!
jayin
修改的评论也不能少于六个字哦!
JellyBool 回复 jayin
修改的评论也不能少于六个字哦!
jayin 回复 JellyBool
修改的评论也不能少于六个字哦!
bluescheung
修改的评论也不能少于六个字哦!