My first project on Laravel with Cards and Notes

Setup MySQL connection in Laravel env

nano .env


Setup authentication

php artisan make:auth
php artisan migrate

This overwrites HomeController.php if already exist so execute at beginning stage of development


Create your database tables, Controller & Model

#Create database table example: cards & notes
php artisan make:migration create_cards_table --create=cards
php artisan make:migration create_notes_table --create=notes

#Refer to below link for database columns

#migrate (lose data)
php artisan migrate
php artisan migrate:refresh
php artisan migrate:reset

#Make controller
php artisan make:controller CardsController
php artisan make:controller NotesController

#Make model
php artisan make:model Card
php artisan make:model Note

# listen to sql query
DB::listen(function($query) {var_dump($query->sql);});

Test your app on terminal first

php artisan tinker

#query table cards

#test model

#test model User (new, save, update, delete)
$user = new App\User;
$user->name = "My Name";
$user->email = "whatever";
$user->name = "My new Name";


Setup your home routes at /routes/web.php

Route::get('/', 'CardsController@home';);


CardsController class

use App\Card;

class CardsController extends Controller{

public function home(){

$cards = Card::all();
return view('', ['cards' => $cards]);


hasMany() Model relationship (example Card has many notes)


class Card extends Model
protected $table = 'cards';
protected $primaryKey = 'id';

public function getNotes(){

return $this->hasMany(Note::class, 'card_id', $this->primaryKey);

HasMany () format

return $this->hasMany('App\Note', 'foreign_key_on_another_table', 'local_key_PK');



Test Card hasMany() Note:class relationship

php artisan tinker

#query first Card
$card = App\Card::first();

#query all the Card's notes

#query the Card's first note

#Same as above but more efficient (doesn't query all notes on the database)

#Attempt saving a note to this card
$card = App\Card::first();
$note = new App\Note;

$card = $card->fresh();



belongsTo() Model relationship (example Note belongs to Card)


class Note extends Model
protected $table = 'notes';
protected $primaryKey = 'nid';

public function belongsToCard(){

return $this->belongsTo(Card::class, 'card_id', 'cid');

belongsTo format

return $this->belongsTo('App\Card', 'foreign_key_on_local', 'other_key_PK_of_another_table');


Test Note belongsTo() Card::class relationship

php artisan tinker

#query first Note
$note = App\Card::first();

#query this note belongsTo which card

#query using your methods


Laravel API


Layout using blade

<!doctype html>

<div class="container">
<div class="row">
<div id="main" class="row">
<footer class="row">



Bootstrap in your head section

<meta charset="UTF-8">

<!-- If IE use the latest rendering engine -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">

<!-- Set the page to the width of the device and set the zoon level -->
<meta name="viewport" content="width = device-width, initial-scale = 1">

<!-- Bootstrap -->
<link rel="stylesheet" href="">

Get the latest CSS Bootstrap version at: or


Provide jQuery before loading bootstrap.min.js

<!-- jquery -->
<script src=""></script>
<!-- bootstrap.min.js-->
<script src=""></script>

Get the latest jquery version at: or
Get the latest bootstrap.min.js at:


Form with csrf

<form method="POST" action="/card/addNote">

<textarea class="form-control" name="body"></textarea>
<input type="submit" value="Add note" class="btn btn-default">

{{ csrf_field() }}


Declare $fillable to fix Mass Assignment Exception on your class

class Note extends Model
     protected $table = 'notes';
     protected $primaryKey = 'nid';

     protected $fillable = ['body', 'abc', 'zyx'];


Add validation to your form

Cleaner to put on contoller

public function addNote(Request $request, int $cid){

$this->validate($request, ['body' => 'required | min:10']);


 If you wish to use Input::all() you may need to use below on your controller

use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Redirect;
public function firstloginhtmlSubmit(Request $request){

$rules = [ 'name' => 'required',
'email' => 'required|email',
'password' => 'required|confirmed' ];

$validator = Validator::make(Input::all(), $rules);


Display validation error on your view

@if (count($errors) > 0)
<div class="alert alert-danger">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>

Give back old user input data that was cleared due to validation error on the form {{ old(‘body’) }}

Display all validation error


<div class="alert alert-danger alert-dismissable">
@foreach($errors->all() as $msg)
<li> {{ $msg }} </li>


Display validation error with Bootstrap

Chose from has-error has-warning has-success

<form method="POST" class="form-group">

<div class="@if($errors->has('body')) has-error @endif">
<textarea class="form-control" name="body">{{$note->body}}</textarea>


Display custom validation error with Bootstrap

<form method="POST" class="form-group">

<div class="@if($errors->has('body')) has-error @endif">
@if ($errors->has('body'))
<p class="help-block">Please enter your message</p>
<textarea class="form-control" name="body">{{$note->body}}</textarea>

 Refer to bootstrap for more options:



class CardsController extends Controller
public function home(){

$cards = Card::paginate(25);

return view('', ['cards' => $cards]);


Display pagination on view

{{ $cards->links() }}


Configure mail

For gmail, port 465 (with SSL) and port 587 (with TLS)




'driver' => env('MAIL_DRIVER', 'smtp'),
'host' => env('MAIL_HOST', ''),
'port' => env('MAIL_PORT', 587),
'from' => ['address' => '', 'name' => 'xyz'],
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
'username' => env('MAIL_USERNAME'),
'password' => env('MAIL_PASSWORD'),
'sendmail' => '/usr/sbin/sendmail -bs',

Clear cache

php artisan config:cache
php artisan config:clear


Disable gmail security (DisplayUnlockCaptcha)

Disable gmail security


Enable 2 factor authentication if you do not wish to disable google security

Generate apppasswords

Step1. Go to
Step2. Select “Security” -> “Basic settings” -> “Less secure apps”
Step3. Go to settings for less secure apps -> Check the radio button “Allow users to manage their access to less secure apps”
Step4. Save the changes
Step5. Open this link being sign in as the super administrator
Step7. Check the radio button Turn On the access for less secure apps
Step8. Unlock Captcha using this link



Make middleware

php artisan make:middleware AdminOnly

Assign Middleware To Routes

# app/Http/Kernel.php

protected $routeMiddleware = [

'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'AdminOnly' => \App\Http\Middleware\AdminOnly::class,


Leave a Comment

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