Migrations
Create articles migration:
$ php artisan make:migration create_articles_table --create="articles"Inside database/migrations find created migration and edit:
2015_07_13_192755_create_articles_table.phpand add these lines to up() method:
Schema::create('articles', function (Blueprint $table) {To execute created migration do:
$table->increments('id');
$table->string('title');
$table->text('body');
$table->text('excerpt')->nullable();
$table->timestamp('published_at');
$table->timestamps();
});
$ php artisan migrate
Routes
Editapp\Http\routes.phpand add this line:
Route::resource('articles', 'ArticlesController');Which is easier way and equal to manually supply all CRUD routes following REST convention like so:
Route::get('articles', 'ArticlesController@index');
Route::get('articles/create', 'ArticlesController@create');
Route::get('articles/{id}', 'ArticlesController@show');
Route::post('articles', 'ArticlesController@store');
Route::get('articles/{id}/edit', 'ArticlesController@edit');
Model
We have articles table, so lets create Article model:$ php artisan make:model ArticleEdit our model app\Article.php and add $fillable fields so we can mass assign them while creating article. Also specify published_at field inside $dates so Laravel threat this field as Carbon date object instead of simple string representation.
class Article extends Model
{
protected $dates = ['published_at'];
protected $fillable = [
'title',
'body',
'published_at'
];
}
Add two rows to article table using Laravel interactive tinker tool:
$ php artisan tinker;Update first article:
$ App\Article::create(['title' => 'My first article', 'body' => 'Article body', 'published_at' => Carbon\Carbon::now()]);
$ App\Article::create(['title' => 'New article', 'body' => 'New body', 'published_at' => Carbon\Carbon::now()]);
$ App\Article::all();
$article = App\Article::find(1);Get collection of articles:
$article->body = 'Lorem ipsum';
$article->save();
App\Article::all();
$articles = App\Article::where('body','Lorem ipsum')->get();Get first article:
$article = App\Article::where('body','Lorem ipsum')->first();
Controller
Let's create plain ArticlesController:$ php artisan make:controller ArticlesController --plainSo now we will create index action to fetch list of articles.
Edit app\Http\Controllers\ArticlesController.php:
public function index()We want to use published() scope while fetching articles to get only those published until today and sort them descending from newest to oldest by published_at using latest(). So let's create published() scope in app\Article.php model. Notation is keyword scope followed by scope name, like this:
{
$articles = Article::latest('published_at')->published()->get();
return view('articles.index', compact('articles'));
}
use Carbon\Carbon;To show details of selected article we need show() action. Edit app\Http\Controllers\ArticlesController.php:
public function scopePublished($query)
{
$query->where('published_at', '<=', Carbon::now());
}
public function show($id)
{
$article = Article::findOrFail($id);
return view('articles.show', compact('article'));
}
View
Inside resources folder create app.blade.php:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
</head>
<body>
<div class="container">
@yield('content')
</div>
@yield('footer')
</body>
</html>
Inside resources\articles create index.blade.php:
@extends('app')
@section('content')
<div class="col-md-12 staff-header">
<h5>Articles</h5>
</div>
<div class="col-xs-12 col-md-12">
@foreach( $articles as $article)
<article>
<h4>
<a href="{{ action('ArticlesController@show', [$article->id]) }}">{{ $article->title }}</a>
</h4>
<h6>{{ $article->body }}</h6>
<br/>
</article>
@endforeach
</div>
@stop
Inside resources\articles create show.blade.php:
@extends('app')
@section('content')
<div class="col-md-12 staff-header">
<h5>{{ $article->title }}</h5>
</div>
<div class="col-xs-12 col-md-12">
<article>
<h6>{{ $article->body }}</h6>
</article>
</div>
@stop