Database Eloquent ORM Reading / Finding with Constraints

In your routes you can test Eloquent reading and finding statements. First include your model to reference, then write your read statements:

use App\Models\Post;

/*
|--------------------------------------------------------------------------
| ELOQUENT ORM (Object Relational Model)
|--------------------------------------------------------------------------
*/

Route::get('/all', function(){
    $posts = Post::all();
    foreach($posts as $post){
        return $post->title;
    }
});

Route::get('/find', function(){
    $post = Post::find(2);
    return $post->title;
});

Route::get('/findwhere', function(){
    $posts = Post::where('id',2)->orderBy('id','desc')->take(1)->get();
    return $posts;
});

Route::get('/findorfail', function(){
    $posts = Post::findOrFail(1);
    return $posts;
});

Route::get('/firstorfail', function(){
    $posts = Post::where('users_count','<',50)->firstOrFail;
    return $posts;
});

The find condition needs the ID of the row in database. The where condition is also looking for the ID of the row (though could look for anything).

Defining a Model Laravel

Models connect to your database. Model is always a singular name, while the database table is the plural name of the model. See example below

<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;
}

This model is named Post which means it automatically will look for a database table named “posts” in lowercase. The default ID it will look for will be named “id”.

You can change the defaults of the table name and id name like this:

<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;
    protected $table = 'posts_table';
    protected $primaryKey = 'post_id';
}

Raw SQL Queries in Laravel

Add these to your routes to see raw SQL working:

Route::get('/insert', function () {
    DB::insert('insert into posts(title, content) values(?,?)',['PHP with Laravel', 'Laravel is the best thing that has happened to PHP']);
});

Route::get('/read', function () {
    $results = DB::select('select * from posts where id=?',[1]);
    foreach($results as $post){
        return $post->title;
    }
});

Route::get('/update', function () {     
    $updated = DB::update('update posts set title="Update title" where id=?',[1]);
    return $updated;
});  

Route::get('/delete', function () {     
    $deleted = DB::delete('delete from posts where id=?',[1]);
    return $deleted;
});  

Add columns to existing tables using migrate

Creates another file name and specifies it targets already created table named “posts”:

php artisan make:migration add_is_admin_column_to_posts_table --table="posts"

Inside your up function add a new column to this table like so:

$table->integer('is_admin')->unsigned();

In your down function make sure to drop the column as well:

$table->dropColumn('is_admin');

Then add this column to database by adding this to terminal:

php artisan migrate

Check phpmyadmin to see new column

Laravel Migrations

Laravel needs an empty database created either through command line or PHPMySQL.

Check .env file that MySQL database name matches with correct username and password.

Open terminal and type:

php artisan migrate

The information for these tables are kept in the database/migrations folder.

Here is a list of all types of migrations that can be done:

  migrate:fresh          Drop all tables and re-run all migrations
  migrate:install        Create the migration repository
  migrate:refresh        Reset and re-run all migrations
  migrate:reset          Rollback all database migrations
  migrate:rollback       Rollback the last database migration
  migrate:status         Show the status of each migration

Passing data to views

One data variable to view

Create a custom route:

Route::get('/post/{id}',[PostsController::class, 'show_post']);

Create custom controller function that passes url data plus a string to the view

public function show_post($id){
    return view('post')->with('id',$id);
}

Create a post.blade.php file and add this line to it:

<h1>Post {{$id}}</h1>

You’ll see the url folder in the page now

Sending multiple data to view

Update your controller function to use compact like so:

public function show_post($id, $name, $another){
    return view('post', compact('id','name','another'));
}

Update route like this:

Route::get('/post/{id}/{name}/{another}',[PostsController::class, 'show_post']);

Update view:

<h1>Post {{$id}} {{$name}} {{$another}}</h1>

Passing data to controller

First Method

In your controller (PostsController), edit one of the functions to pass a variable like this:

public function index($id)
{
    return "its working ".$id;
}

Edit your routes to accept the variable like so:

Route::get('/post/{id}', [PostsController::class, 'index']);

Second Method

Add your controller as a resource like this:

Route::resource('posts', PostsController::class);

Then type this into terminal to find which method accepts variables like this:

php artisan route:list

GET|HEAD        posts ........................................... posts.index › PostsController@index  
  POST            posts ........................................... posts.store › PostsController@store  
  GET|HEAD        posts/create .................................. posts.create › PostsController@create  
  GET|HEAD        posts/{post} ...................................... posts.show › PostsController@show  
  PUT|PATCH       posts/{post} .................................. posts.update › PostsController@update  
  DELETE          posts/{post} ................................ posts.destroy › PostsController@destroy  
  GET|HEAD        posts/{post}/edit ................................. posts.edit › PostsController@edit

Method show accepts a variable. So edit the show function in PostsController to display the variable on screen:

public function show($id)
{
    return "hi ".$id;
}

Target class controller does not exist – Laravel 8

In previous releases of Laravel, the RouteServiceProvider contained a $namespace property. This property’s value would automatically be prefixed onto controller route definitions and calls to the action helper / URL::action method. In Laravel 8.x, this property is null by default. This means that no automatic namespace prefixing will be done by Laravel.

Laravel 8.x Docs – Release Notes

You need to use the Fully Qualified Class Name for your Controllers when referring to them in your routes when not using the namespace prefixing.

use App\Http\Controllers\UserController;

Route::get('/users', [UserController::class, 'index']); 
// or 
Route::get('/users', 'App\Http\Controllers\UserController@index');