Laravel

Laravel is a free, open-source and most popular PHP web framework, created by Taylor Otwell in June 2011. It is based on symfony and follows the Model-View-Controller (MVC) architectural pattern for the development of web application.

Eloquent

Laravel has an object-relational mapper (ORM) named “Eloquent” which allows you to work with your database. Eloquent is a new technique to work with the database query using the model in Laravel. Each database table had a corresponding “Model” which we will use to interact with that table.
Eloquent provide simple and beautiful syntax to gain complex queries in few seconds without writing long queries.

Thus each database table has a corresponding “Model” which we can use to interact with the database table. The Model allows you to execute a query for data and also insert a new record in the database table.

To get started, let’s create a Model. Typically, Model will be store inside the app folder. We can easily create the model instance by using the make:model Artisan Command.

php artisan make:model Category

If you would like to generate the database migration when you create the model then you can use

php artisan make:model Category --migration 
php artisan make:model Category -m

Now let’s take an example Category model, which we will be using to store and fetch information from our categories table.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    //
}

Relationship

A relationship, in the context to the database, is connection or link between two tables through a primary key and a reference key. One table has a foreign key that references the primary key of another table. Relationship allow relational databases to split and store the data in various tables.

For example, a post may have many category, or an order could be related to the user who placed it. Eloquent makes managing and working with these relationships easy, and supports different types of relationships:

  • One To One
  • One To Many
  • Polymorphic One To Many
  • Many To Many
  • Polymorphic Many To Many

Defining Relationship

Eloquent relationship are defined as a function or a method on your model classes. Relationship also serves as a powerful Query Builder like model. By Defining a relationships as a methods provides powerful method chaining and querying capabilities.

$user->categories()->where('id', 1)->get();

One To One

One to one relationship is a very simple relation. Here, one table can only be associated with other single table.

For example, suppose we have two models User & Role and two table users and roles.

  RULES :

  • The User can have only one Role
  • One Role belongs to only one User

To define this relationship, we place a role method on the User model. The role method should call the hasOne method and return its result:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    public function role()
    {
        return $this->hasOne('App\Role');
    }
}

Eloquent model determines the foreign key of the relationship based on the model name. In this case, the Role model is automatically assumed to have an user_id foreign key. If you wish to override this convention, you may pass aa additional argument to the hasOne method:

Note: If your primary key is other than the id on the parent table(users), then your have to pass it as a ‘local_key’.

//Passing foreign key
return $this->hasOne('App\Role', 'foreign_key');

//Passing foreign key with primary key
return $this->hasOne('App\Role', 'foreign_key', 'local_key')
Inverse One To One

So, we can access the Role model from our User model. Now, let’s define a relationship on the Role model that will let us to access the User that owns the role. We can define the inverse of a hasOne relationship using the belongsTo method.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Role extends Model
{
    /**
     * Get the user that owns the phone.
     */
    public function user()
    {
        return $this->belongsTo('App\User');
    }
}

In the example above, Eloquent will try to match the user_id from the Role model to an id on the User model. Eloquent determines the default foreign key name by examining the name of the relationship method and suffixing the method name with _id . However, if the foreign key on the Role model is not user_id, you may pass a additional argument to the belongsTo method:

Note : If your parent model does not use  id as its primary key, or you wish to join the child model to a different column, you may pass a third argument to the belongsTo method specifying your parent table’s custom key:

return $this->belongsTo('App\User', 'foreign_key');

return $this->belongsTo('App\User', 'foreign_key', 'other_key');

Database Migration

In Database Users database migration is created automatically. Let’s take a look of both the users and roles database migration.

Users :

Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });

Roles :

Schema::create('roles', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedInteger('user_id');
            $table->foreign('user_id')->references('id')->on('users');
            $table->string('role_name');
        });

Saving Data
// Create relation between User and Role.
$user->role()->save($role);

// Create relation between Role and User.
$role->user()->associate($user);

Fetching Data
// Get User Role
User::find(1)->role;

// Get Role User
Role::find(1)->user;

One To Many

A one-to-many relationship is used to define relationships where a single model owns two or more other models.

Same as other relationships, we can define one-to-many relationships by placing a method on an Eloquent model.

  RULES :

  • The User can create many Categories
  • One Category belongs to only one User

To define this relationship, we place a categories method on the User model. The categories method should call the hasMany method and return its result:

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
   ...

    /**
     * User can have many categories
    */
    public function categories(){
        return $this->hasMany('App\Category');
    }
}

Remember, Eloquent will automatically determine the proper foreign key column on the Category model. By convention, Eloquent will take the “snake case” name of the owning model and suffix it with _id. So, for this example, Eloquent will assume the foreign key on the Category model is user_id.

Like the hasOne method, you may also override the foreign and local keys by passing additional arguments to the hasMany method:

return $this->hasMany('App\Category', 'foreign_key');

return $this->hasMany('App\Category', 'foreign_key', 'local_key');

Inverse One To Many

Now that we can access all of a categories created by users, let’s define a relationship to allow a categories to access its parent users. To define the inverse of a hasMany relationship, define a relationship function on the child model which calls the belongsTo method:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    /**
     * Category can have one user
    */
    public function user(){
        return $this->belongsTo('App\User');
    }
}

Like the inverse one to one relationship , you may also override the foreign and local keys by passing additional arguments

return $this->belongsTo('App\User', 'foreign_key')

return $this->belongsTo('App\User', 'foreign_key', 'other_key');

Database Migration

In Database Users database migration is created automatically. Let’s take a look of both the users and categories database migration.

Users :

Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });

categories :

Schema::create('categories', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedInteger('user_id');
            $table->foreign('user_id')->references('id')->on('users');
            $table->string('title');
            $table->timestamps();
        });

Saving Data
// Create relation between User and Category.
$user->categories()->saveMany([$category, $category]);

// Or use the save() function for single model.
$user->categories()->save($category);

// Create relation between Category and User.
$category->user()->associate($user)->save();
Fetching Data
//Get User Category
User::find(1)->categories;

//Get Category User
Category::find(2)->user->name;

Polymorphic One To Many

Polymorphic One To Many Relation is similar to one to many relation. This type of relation is used when the target model can belong to more than one type of model on a single association. For example user on your application can comment on both the post and videos.

  RULES :

  • The User can comment on post
  • The User can comment on videos
  • Comments can be done on both post and videos

To define this relationship, we place a comment method on the Post model as well as in Video model. The comment method should call the morphMany method and return its result. In Comment class we place
commentable method which should call morphTo method.

Post Model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    /**
     * Get all of the post's comments.
     */
    public function comments()
    {
        return $this->morphMany('App\Comment', 'commentable');
    }
}

Video Model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Video extends Model
{
    /**
     * Get all of the video's comments.
     */
    public function comments()
    {
        return $this->morphMany('App\Comment', 'commentable');
    }
}

Comment Model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
    /**
     * Get all of the owning commentable models.
     */
    public function commentable()
    {
        return $this->morphTo();
    }
}

Database Migration

Post :

Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->string('body');
            $table->timestamps();
        });

Videos :

Schema::create('videos', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->string('url');
            $table->timestamps();
        });

Comments :

Schema::create('comments', function (Blueprint $table) {
            $table->increments('id');
            $table->string('body');
            $table->integer('commentable_id');
            $table->string('commentable_type');
            $table->timestamps();
        });

Saving Data
// Post Comment
$post = Post::find(1);	
 
$comment = new Comment;
$comment->body = "Hi blog.sushankpokharel.com.np";
 
$post->comments()->save($comment);

//Video Comment
$video = Video::find(1);	
 
$comment = new Comment;
$comment->body = "Hi blog.sushankpokharel.com.np";
 
$video->comments()->save($comment);

Fetching Data
//Get Post Comment
Post::find(1)->comments

//Get Video Comment
Video::find(1)->comments

Many To Many

Many To Many relationship is slightly more complicated than One To One and One To Many relationship. An example of a relationship is a user with many roles, while the roles has also many users.

RULES :

  • The User can have many Role
  • The Role can have many User

Many-to-many relationships are defined by writing a method that returns the result of the belongsToMany method.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * The roles that belong to the user.
     */
    public function roles()
    {
        return $this->belongsToMany('App\Role');
    }
}

Inverse Many To Many

To define the inverse of a many-to-many relationship, you place another call to belongsToMany on your related model. To continue our user roles example, let’s define the users method on the Role model:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Role extends Model
{
    /**
     * The users that belong to the role.
     */
    public function users()
    {
        return $this->belongsToMany('App\User');
    }
}

Database Migration

To define this relationship, three database tables are needed: users , roles, and role_user. The role_user table is derived from the alphabetical order of the related model names, and contains the user_id and role_id columns.

Users :

Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });

Roles :

Schema::create('roles', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
        });

Role_user:

Schema::create('roles', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedInteger('user_id');
            $table->foreign('user_id')->references('id')->on('users');
            $table->unsignedInteger('role_id');
            $table->foreign('role_id')->references('id')->on('roles');
        });

Saving Data
// Create relation between User and Phone.
$user->roles()->attach([$role1->id, $role->id]);

// Or use the sync() function to prevent duplicated relations.
$user->roles()->sync([$role1->id, $role2->id]);

// Create relation between Phone and User.
$role->users()->attach([$user1->id, $user2->id]);

// Or use the sync() function to prevent duplicated relations.
$role->users()->sync([$user1->id, $user2->id]);

Fetching Data
//Get user role
User::find(1)->roles

//Get roles user
Role::find(1)->users

Polymorphic Many To Many

Like Many To Many relationship Polymorphic Many To Many relationship is slightly more complicated than Polymorphic One To Many relation. For example your application can share the single list unique tag to post and videos.

RULES :

  • Post have the Tags
  • Video have the Tags
  • Tags are unique and shared by Post and Video

Post Model :

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    /**
     * Get all of the tags for the post.
     */
    public function tags()
    {
        return $this->morphToMany('App\Tag', 'taggable');
    }
}

Video Model :

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Video extends Model
{
    /**
     * Get all of the tags for the post.
     */
    public function tags()
    {
        return $this->morphToMany('App\Tag', 'taggable');
    }
}

Next, on the Tag model, you should define a method for each of its related models. So, for this example, we will define a posts method and a videos method:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Tag extends Model
{
    /**
     * Get all of the posts that are assigned this tag.
     */
    public function posts()
    {
        return $this->morphedByMany('App\Post', 'taggable');
    }

    /**
     * Get all of the videos that are assigned this tag.
     */
    public function videos()
    {
        return $this->morphedByMany('App\Video', 'taggable');
    }
}

Database Migration

posts :

Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->string('body');
            $table->timestamps();
        });

videos :

Schema::create('videos', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->string('url');
            $table->timestamps();
        });

tags :

Schema::create('tags', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->timestamps();
        });

taggables :

Schema::create('taggables', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('tag_id');
            $table->integer('taggable_id');
            $table->string('taggable_type');
            $table->timestamps();
        });

Saving Data
// For single model use save function
$post->tags()->save($tag);
$video->tags()->save($tag);

//For saving multiple related model
$post->tags()->saveMany([$tag1, $tag2]);
$video->tags()->saveMany([$tag1, $tag2]);

//To attach a tag to a post for inserting a record
$post->tags()->attach([$tag1->id, $tag2->id]);
$video->tags()->attach([$tag1->id, $tag2->id]);

//Use a sync function to prevent a duplicated relation
$post->tags()->sync([$tag1->id, $tag2->id]);
$video->tags()->sync([$tag1->id, $tag2->id]);

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *