ホームページ >バックエンド開発 >PHPチュートリアル >Laravel 5 つの基本 (10) - 日付、ミューテーター、スコープ
Laravel 5 の基本 (10) - 日付、ミューテーター、スコープ
以前の解決策では、published_at に現在の日付を直接割り当てるのは、実際には一時的な解決策ですが、公開日を設定する必要があります。次の 2 日までリリースされるので、この問題を修正しましょう。
最初にコントローラーを変更します:
<code> public function store() { Article::create(Request::all()); return redirect('articles'); }</code>
次にビューを変更して公開日フィールドを追加します
<code>@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</code>
OK、新しい記事を追加して日付を入力しましょう将来の特定の日に設定されていますが、記事が最初に直接表示されますが、これは必要なものではありません。当日にそれを見せなければなりません。もちろん、0時ではなく朝8時に表示するなど、より具体的にする必要があります。ミューテーター (つまり、他の言語の属性セッター) を追加し、モデル
<code><?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); }}</code>
を変更し、新しいレコードを追加して、データベースを確認できます。時刻は正しく設定されていますが、ホームページは異なります。今後の投稿が公開される前に引き続き表示され、変更されます。
<code> 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')); }</code>
上記の解決策は機能しますが、クエリ ステートメントが長すぎます。 Laravel が提供するスコープを使用すると、作業を簡素化できます。いわゆるスコープは、クエリ プロセスで使用される中間クエリ結果として理解できます。たとえば、公開されたスコープを定義すると、現在公開されているすべての記事が返され、モデルを変更できるようになります。
<code> //设置scope,遵守命名规则 public function scopePublished($query) { $query->where('published_at', '<=', Carbon::now()); }</code>
スコープを使用するようにコントローラーを変更します
<code> 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')); }</code>
結果は同じですが、複雑なクエリではスコープを使用してタスクを分解したり、クエリを再利用したりできます。
まだ公開されていないすべての記事をクエリする新しいクエリを追加しましょう。スコープ
<code> public function scopeUnpublished($query) { $query->where('published_at', '>', Carbon::now()); }</code>
をモデルに追加し、unpulished
<code> 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')); }</code>
を使用するようにコントローラーを変更します。show
メソッドで dd($article->published_at)
を使用して結果を表示するとします。 、dd($article->created_at);
の場合、結果は異なります。前者では独自のフィールドを作成しますが、後者では、CreateArticleTable
の $table->timestamp()
によって自動的に生成されます。自動生成されたフィールドは Carbon
タイプとして表示されますが、私たちのフィールドは文字列です。たとえば、Crabon 型を使用すると、dd($article->created_at->diffForHumans());
とこの 1 hour ago
の結果を出力できますが、published_at
は出力できません。変更するにはどうすればよいですか?モデルを変更し、laravel に published_at
が日付であることを伝えます。
<code> protected $dates = ['published_at'];</code>
もう一度 dd($article->published_at->diffForHumans());
を使用すると、結果は 3 days from now
と表示され、ビンゴ!