Home > Article > Backend Development > Laravel 5 framework learning date, Mutator and Scope, laravelmutator_PHP tutorial
In our previous solution, directly assigning the value of published_at to the current date is actually a temporary solution. We need to set a release date, maybe 2 days in the future, so let's fix this question.
First modify the controller:
public function store() { Article::create(Request::all()); return redirect('articles'); }
Then modify the view and add the release date field
@extends('layout') @section('content') <h1>Write a New Article</h1> <hr/> {{--使用我们添加的 illuminate\html 开源库--}} {!! Form::open(['url' => 'articles']) !!} <div class="form-group"> {!! Form::label('title', 'Title:') !!} {!! Form::text('title', null, ['class' => 'form-control']) !!} </div> <div class="form-group"> {!! Form::label('body', 'Body:') !!} {!! Form::textarea('body', null, ['class' => 'form-control']) !!} </div> <div class="form-group"> {!! Form::label('published_at', 'Publish On:') !!} {!! Form::input('date', 'published_at', date('Y-m-d'), ['class' => 'form-control']) !!} </div> <div class="form-group"> {!! Form::submit('Add Article', ['class' => 'btn btn-primary form-control']) !!} </div> {!! Form::close() !!} @stop
ok, let’s add a new article and set the date to a day in the future, but the article will be displayed directly at the beginning, which is not what we need. We need to show it on that day. Of course, we need to be more specific, such as displaying it at 8:00 in the morning instead of 0 o'clock. We can add a mutator (that is, a property setter in other languages) and modify our model
<?php namespace App; use DateTime; use Illuminate\Database\Eloquent\Model; class Article extends Model { protected $fillable = [ 'title', 'body', 'published_at' ]; //属性设置其要遵守格式约定 // set属性Attribute public function setPublishedAtAttribute($date) { $this->attributes['published_at'] = Carbon::createFromFormat('Y-m-d', $date)->hour(8)->minute(0)->second(0); } }
Add a new record, check the database, we have set the time correctly, but our homepage still shows the articles published in the future, we modify it.
public function index() { //$articles = Article::latest('published_at')->get(); $articles = Article::latest('published_at')->where('published_at', '<=', Carbon::now())->get(); return view('articles.index', compact('articles')); }
The above solution works, but the query statement is too long. We can use the scope provided by Laravel to simplify our work. The so-called scope can be understood as the intermediate query results used in the query process. For example, if we define a published scope, it can return all currently published articles, allowing us to modify the model.
//设置scope,遵守命名规则 public function scopePublished($query) { $query->where('published_at', '<=', Carbon::now()); }
Modify the controller to use scope
public function index() { //$articles = Article::latest('published_at')->get(); //$articles = Article::latest('published_at')->where('published_at', '<=', Carbon::now())->get(); $articles = Article::latest('published_at')->published()->get(); return view('articles.index', compact('articles')); }
The result is the same, but in complex queries we can use scope to break down our tasks, or reuse queries.
Let’s add a new query to query all articles that have not been published yet. Add scope
to the modelpublic function scopeUnpublished($query) { $query->where('published_at', '>', Carbon::now()); }
Modify the controller to use unpulished
public function index() { //$articles = Article::latest('published_at')->get(); //$articles = Article::latest('published_at')->where('published_at', '<=', Carbon::now())->get(); //$articles = Article::latest('published_at')->published()->get(); $articles = Article::latest('published_at')->Unpublished()->get(); return view('articles.index', compact('articles')); }
One more thing! If we use dd($article->published_at) in the show method, the result is different from dd($article->created_at);. In the former, we use our own fields, The latter is automatically generated via $table->timestamp() in CreateArticleTable. The automatically generated field is shown as Carbon type, while ours is String. There are many advantages to using the Crabon type. For example, you can output dd($article->created_at->diffForHumans()); , this kind of 1 hour ago result, but our published_at cannot. How to modify it? Modify the model and tell laravel that published_at is the date.
protected $dates = ['published_at'];
Use dd($article->published_at->diffForHumans()); again, the result shows 3 days from now, Bingo!
The above is the entire content of this article. I hope it can help everyone learn the Laravel5 framework.