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

WBOY
Release: 2016-06-23 13:26:34
Original
897 people have browsed it

原文来自https://laravist.com/article/20

Laravist是我刚刚上线的Laravel社区,有任何与Laravel相关的问题可以到这里来问我,我会尽力去帮大家解决问题,后期会尝试录制一些视频教程,形式大概是这样的

https://laravist.com/lesson/2

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

注册路由

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

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

这个路由接受一个参数: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'));    }
Copy after login

很熟悉地,我们首先根据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
Copy after login

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

我们使用了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']) !!}
Copy after login

你依然会得到相同的效果,但是这里为了更清晰,我直接赋了$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    }
Copy after login

这里需要说明一下,类似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');
Copy after login

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

编写update()

在ArticleController中增加update()方法:

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

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

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('/');    }
Copy after login

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

Bang,大工告成!!

总结

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

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

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

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

Happy Hacking

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template