In this article we will create a simple blog using Laravel 4. Our blog application will have the following features:
- Display posts with read more links on home page.
- Users will able to search posts on blog.
- Display single post with comments.
- Allow users to post comments.
- Administrator will be able to perform CRUD operations on posts and comments.
- Administrator will be able to moderate comments.
Laravel Quick Installation and Setup
I will assume that you have a working installation of Laravel 4. Otherwise, you can follow these steps to install and setup Laravel 4:
- Install Laravel 4 by following instructions provided here.
- Create a database using the MySQL terminal client:
┌─[usm4n@usm4n-desktop]―[~] └─•mysql -u root -p Enter password: mysql> create database laravel; Query OK, 1 row affected (0.00 sec)
- Configure database in /app/config/database.php:
- 'mysql' => array(
- 'driver' => 'mysql',
- 'host' => 'localhost',
- 'database' => 'laravel',
- 'username' => 'root',
- 'password' => 'very_secret_password',
- 'charset' => 'utf8',
- 'collation' => 'utf8_unicode_ci',
- 'prefix' => '',
- ),
Creating Database Migrations
In this section, we will create database tables for our blog application using Laravel Database Migrations. Our application will be utilizing
posts
and comments
tables to store articles and user comments respectively. (Read more on migrations here)QUICK TIP:
We useartisan migrate:make create_tablename_table
andartisan migrate
commands to create and run migrations respectively.
Migration
class
for posts
table:
- <?php
- use Illuminate\Database\Migrations\Migration;
- use Illuminate\Database\Schema\Blueprint;
- class CreatePostsTable extends Migration {
- /**
- * Run the migrations.
- *
- * @return void
- */
- public function up()
- {
- Schema::create('posts', function(Blueprint $table) {
- $table->increments('id');
- $table->string('title');
- $table->string('read_more');
- $table->text('content');
- $table->unsignedInteger('comment_count');
- $table->timestamps();
- $table->engine = 'MyISAM';
- });
- DB::statement('ALTER TABLE posts ADD FULLTEXT search(title, content)');
- }
- /**
- * Reverse the migrations.
- *
- * @return void
- */
- public function down()
- {
- Schema::table('posts', function(Blueprint $table) {
- $table->dropIndex('search');
- $table->drop();
- });
- }
- }
Note that, I have used
$table->engine='MyISAM'
and added a composite fulltext index usingtitle
and content
columns. This will allow us to utilize MySQL fulltext search on posts table.
Code for
comments
table migration:
- <?php
- use Illuminate\Database\Migrations\Migration;
- use Illuminate\Database\Schema\Blueprint;
- class CreateCommentsTable extends Migration {
- /**
- * Run the migrations.
- *
- * @return void
- */
- public function up()
- {
- Schema::create('comments', function(Blueprint $table) {
- $table->increments('id');
- $table->unsignedInteger('post_id');
- $table->string('commenter');
- $table->string('email');
- $table->text('comment');
- $table->boolean('approved');
- $table->timestamps();
- });
- }
- /**
- * Reverse the migrations.
- *
- * @return void
- */
- public function down()
- {
- Schema::drop('comments');
- }
- }
The
post_id
field will help us in defining one to many relationship using Eloquent ORM seamlessly. We will use approved
field of comments table for comments moderation purpose. We will cover the users
table in Authentication Section.Creating Models Using Eloquent ORM
The Eloquent ORM included with Laravel provides a beautiful, simple ActiveRecord implementation for working with your database. Each database table has a corresponding “Model” which is used to interact with that table.Laravel Eloquent ORM Documentation
We use singular variants of table names as our Eloqent Model names, this convention helps the Eloquent to figure out the table to be used with a particular Model. For instance: if the name of the Model is
Post
Eloquent will assume a table with name posts
to be used.
Here is the code for our
Post
and Comment
Models:
- <?php
- // file: app/models/Post.php
- class Post extends Eloquent {
- public function comments()
- {
- return $this->hasMany('Comment');
- }
- }
- // file: app/models/Comment.php
- class Comment extends Eloquent {
- public function post()
- {
- return $this->belongsTo('Post');
- }
- }
Seeding Database Tables
We will use a single
PostCommentSeeder
class to populate both posts
and comments
tables.QUICK TIP:
We useartisan db:seed
command to seed the database.
Code for
PostCommentSeeder
:
- <?php
- class PostCommentSeeder extends Seeder {
- public function run()
- {
- $content = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.
- Praesent vel ligula scelerisque, vehicula dui eu, fermentum velit.
- Phasellus ac ornare eros, quis malesuada augue. Nunc ac nibh at mauris dapibus fermentum.
- In in aliquet nisi, ut scelerisque arcu. Integer tempor, nunc ac lacinia cursus,
- mauris justo volutpat elit,
- eget accumsan nulla nisi ut nisi. Etiam non convallis ligula. Nulla urna augue,
- dignissim ac semper in, ornare ac mauris. Duis nec felis mauris.';
- for( $i = 1 ; $i <= 20 ; $i++ )
- {
- $post = new Post;
- $post->title = "Post no $i";
- $post->read_more = substr($content, 0, 120);
- $post->content = $content;
- $post->save();
- $maxComments = mt_rand(3,15);
- for( $j = 1 ; $j <= $maxComments; $j++)
- {
- $comment = new Comment;
- $comment->commenter = 'xyz';
- $comment->comment = substr($content, 0, 120);
- $comment->email = 'xyz@xmail.com';
- $comment->approved = 1;
- $post->comments()->save($comment);
- $post->increment('comment_count');
- }
- }
- }
- }
The outer for loop creates a new
Post
Model on each iteration and saves it after setting the properties: title
, read_more
, content
. The inner loop creates random number of comments for each Post
and increments the comment_count
in posts
table.The ‘artisan tinker’ Command
The Artisan CLI tool provides us with an easy way to interact with Laravel application from command line. We use
artisan tinker
command to use the interactive shell. Let’s practice some Eloquent queries on our test data.┌─[usm4n@usm4n-desktop]―[~] └─•artisan tinker >
Find By Id Using find()
>$post = Post::find(2); >$post->setHidden(['content','read_more','updated_at']); >echo $post; {"id":"2","title":"Post no 2","comment_count":"7","created_at":"2014-01-06 09:43:44"}
Limit No Of Records Using take() And skip()
>$post = Post::skip(5)->take(2)->get(); >foreach($post as $value) echo "post id:$value->id "; post id:6 post id:7
Using select() And first()
>$post = Post::select('id','title')->first(); >echo $post; {"id":"1","title":"Post no 1"}
Using where() With select()
>$post = Post::select('id','title')->where('id','=',10)->first(); >echo $post; {"id":"10","title":"Post no 10"}
Getting Related Records Using Dynamic Property
>$post = Post::find(4); >echo $post->comments[0]->commenter; xyz
Getting Parent Records From Child Model
>$comment = Comment::find(1); >echo $comment->post->title; Post no 1
For a complete reference on Eloquent ORM queries visit official Eloquent Documentation Page.
That’s all for now. Thanks and Regards!