이전 해결 방법에서 게시 날짜를 직접 지정하는 것은 실제로 임시 해결 방법이므로 게시 날짜를 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>
자, 새 기사를 추가하고 날짜를 미래의 날짜로 설정해 보겠습니다. 그런데 기사가 처음에 바로 표시되는데 이는 우리에게 필요한 것이 아닙니다. 그날 보여줘야 해요. 물론 0시가 아닌 아침 8시에 표시하는 등 좀 더 구체적으로 해야 합니다. mutator(즉, 다른 언어의 속성 설정자)를 추가하고 모델을 수정할 수 있습니다
<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>
풀리지 않은 상태로 사용할 수 있도록 컨트롤러 수정
<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()
유형으로 표시되는 반면, 우리의 필드는 문자열입니다. 예를 들어 Crabon 유형을 사용하면 Carbon
및 이 dd($article->created_at->diffForHumans());
결과를 출력할 수 있지만 1 hour ago
은 출력할 수 없다는 장점이 있습니다. 어떻게 수정하나요? 모델을 수정하고 laravel에 published_at
가 날짜임을 알립니다. published_at
<code> protected $dates = ['published_at'];</code>
을 사용하면 결과는 dd($article->published_at->diffForHumans());
으로 표시됩니다. 빙고! 3 days from now