<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: WAIYL KARIM</title>
    <description>The latest articles on DEV Community by WAIYL KARIM (@waiylkarim).</description>
    <link>https://dev.to/waiylkarim</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F425728%2F5fac97c4-0a05-429a-8d22-28d8d9f11afa.jpeg</url>
      <title>DEV Community: WAIYL KARIM</title>
      <link>https://dev.to/waiylkarim</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/waiylkarim"/>
    <language>en</language>
    <item>
      <title>Datatables: Laravel Jetsteam Inertia</title>
      <dc:creator>WAIYL KARIM</dc:creator>
      <pubDate>Mon, 26 Jul 2021 19:08:31 +0000</pubDate>
      <link>https://dev.to/waiylkarim/datatables-laravel-jetsteam-inertial-2p5d</link>
      <guid>https://dev.to/waiylkarim/datatables-laravel-jetsteam-inertial-2p5d</guid>
      <description>&lt;p&gt;When I first was trying to set my project using Laravel Jetstream with Inertia and VueJs I spent so much time trying to figure out how to implement jQuery Datatables in my project. In this article I'm going to show you how to do just that step by step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up your Laravel Project
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer create-project laravel/laravel my-crm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or via &lt;code&gt;laravel&lt;/code&gt; command if you have that installed&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;laravel new my-crm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next let's install &lt;code&gt;Jetstream&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require laravel/jetstream
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install Inertia with Vuejs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan jetstream:install inertia
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install &amp;amp; build NPM dependencies&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install

npm dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Migrate your database&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Install the amazing datatables laravel package by Yajra
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require yajra/laravel-datatables-oracle:"~9.0"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Install Datatables
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install datatables.net-dt

npm i jquery
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Implement Datatables
&lt;/h2&gt;

&lt;p&gt;On your &lt;code&gt;web.php&lt;/code&gt; routes file, let's add necessary routes to load our resources&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Route::resource('users', UsersController::class);

Route::name('users.datatables')-&amp;gt;get('users', [UsersController::class, 'datatables']);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, create a &lt;code&gt;UsersController&lt;/code&gt; and add the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;
use Inertia\Inertia;

class UsersController extends Controller
{
    /**
     * Datatable Columns Array
     *
     * @var Array
     */
    private $datatableColumns;

    /**
     * Datatable Headers Array
     *
     * @var Array
     */
    private $datatableHeaders;

    /**
     * Datatables Data URL
     *
     * @var String
     */
    private $datatableUrl;

    /**
     * Controller constructor
     *
     * @return void
     */
    public function __construct() {     
        $this-&amp;gt;datatableHeaders = [
            'ID', 
            'Name', 
            'Email'
        ];

        $this-&amp;gt;datatableColumns = [
            ['data' =&amp;gt; 'id'],
            ['data' =&amp;gt; 'name'],
            ['data' =&amp;gt; 'email']
        ];

        $this-&amp;gt;datatableUrl = route('users.datatables');
    }

    /**
     * Get datatables JSON Response
     *
     * @return \Illuminate\Http\Response
     */
    public function datatables() {
        $datatables = datatables()
            -&amp;gt;of(User::query())
            -&amp;gt;addColumn('id', fn($user) =&amp;gt; $user-&amp;gt;id)
            -&amp;gt;addColumn('name', fn($user) =&amp;gt; $user-&amp;gt;name)
            -&amp;gt;addColumn('email', fn($user) =&amp;gt; $user-&amp;gt;email)
            -&amp;gt;toArray();

        return response()-&amp;gt;json($datatables);
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        return Inertia::render('Users/Index')
            -&amp;gt;with('datatableUrl', $this-&amp;gt;datatableUrl)
            -&amp;gt;with('datatableColumns', $this-&amp;gt;datatableColumns)
            -&amp;gt;with('datatableHeaders', $this-&amp;gt;datatableHeaders);
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we've got that out of the way, let's build our Vuejs components.&lt;/p&gt;

&lt;p&gt;The first component we will be creating is the &lt;code&gt;Users/Index.vue&lt;/code&gt; component. Inside your &lt;code&gt;resources/js&lt;/code&gt; folder create a new folder called &lt;code&gt;Users&lt;/code&gt; and inside this folder create a &lt;code&gt;.vue&lt;/code&gt; file called &lt;code&gt;Index.vue&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// resources/js/Pages/Users/Index.vue
&amp;lt;template&amp;gt;
        &amp;lt;div class="bg-white rounded-lg shadow-md mx-4 p-6"&amp;gt;
                 &amp;lt;!-- we will display our datatable here --&amp;gt;
        &amp;lt;/div&amp;gt;

&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
    export default {

    }
&amp;lt;/script&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will get back and change this file later.&lt;/p&gt;

&lt;p&gt;Now let's create our &lt;code&gt;Datatable&lt;/code&gt; component. &lt;/p&gt;

&lt;p&gt;Again inside &lt;code&gt;resources/js&lt;/code&gt; add a new folder called &lt;code&gt;Shared&lt;/code&gt; and inside this folder create file called &lt;code&gt;Datatable.vue&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// resources/js/Shared/Datatable.vue

&amp;lt;template&amp;gt;
    &amp;lt;div&amp;gt;
        &amp;lt;table class="table table-hover table-bordered" id="dt-users"&amp;gt;
            &amp;lt;thead class="border-1 rounded-sm text-white border-gray-800 bg-gray-900"&amp;gt;
                &amp;lt;tr&amp;gt;
                    &amp;lt;th v-for="header in headers" :key="header.id"&amp;gt;{{ header }}&amp;lt;/th&amp;gt;
                &amp;lt;/tr&amp;gt;
            &amp;lt;/thead&amp;gt;
        &amp;lt;/table&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
    import 'jquery/dist/jquery.min.js';
    import "datatables.net-dt/js/dataTables.dataTables"
    import $ from 'jquery'; 

    export default {
        props: ['url', 'columns', 'headers'],
        mounted(){
            let datatable = $('#dt-users').on('processing.dt', function(e, settings, processing) {
                    if (processing) {
                        $('table').addClass('opacity-25');
                    }else {
                        $('table').removeClass('opacity-25');
                    }
                }).DataTable({
                ajax: {
                    url: this.url,
                },
                serverSide: true,
                processing: true,
                paging: true,
                columns: this.columns,
            });

        },
    }
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go back to &lt;code&gt;resources/js/Pages/Users/Index.vue&lt;/code&gt; and import this file as followed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// final version of resources/js/Users/Index.vue

&amp;lt;template&amp;gt;
    &amp;lt;div class="bg-white rounded-lg shadow-md mx-4 p-6"&amp;gt;
        &amp;lt;Datatable 
            :url="datatableUrl" 
            :headers="datatableHeaders"
            :columns="datatableColumns"
        /&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
    import Datatable from '@/Shared/Datatable'

    export default {
        components: {
            Datatable,
        },
        props: ['datatableUrl', 'datatableColumns', 'datatableHeaders'],
    }
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it! Leave questions in the comment section.&lt;/p&gt;

&lt;p&gt;Happy coding.&lt;/p&gt;

&lt;p&gt;Cover image credit &lt;a href="https://www.freepik.com/pikisuperstar"&gt;pikisuperstar&lt;/a&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>vue</category>
      <category>jetstrea</category>
      <category>inertia</category>
    </item>
    <item>
      <title>Multi-tenancy with Laravel (dynamic databases)</title>
      <dc:creator>WAIYL KARIM</dc:creator>
      <pubDate>Sun, 18 Jul 2021 18:19:19 +0000</pubDate>
      <link>https://dev.to/waiylkarim/multi-tenancy-with-laravel-42b2</link>
      <guid>https://dev.to/waiylkarim/multi-tenancy-with-laravel-42b2</guid>
      <description>&lt;p&gt;Like many developers before me when it comes to a web project, PHP with Laravel is my go to technology for it is not only making my life as a developer a lot easier but fun as well.&lt;/p&gt;

&lt;p&gt;However when my team and I have been working on a project for one of our clients that requires dynamic database creation we found ourselves between doing it the Laravel way or doing our way.&lt;/p&gt;

&lt;p&gt;I will take the chance in this flash article to explain the problem with doing it the traditional Laravel way and doing it your own way and I will be expecting the experts amongst you to share in the comments section other ways they would use to tackle this challenge.&lt;/p&gt;

&lt;p&gt;Say we have a web-based app whose master will be required to create a new instance of the app for every client. All of these instances are being hosted on the same server which means every instance should have its own database hence multi-tenant.&lt;/p&gt;

&lt;p&gt;If you wish to do it the Laravel way you need to manually add something like this for every database in &lt;code&gt;config/database.php&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        'mysql' =&amp;gt; [
            'driver' =&amp;gt; 'mysql',
            'url' =&amp;gt; env('DATABASE_URL'),
            'host' =&amp;gt; env('DB_HOST', '127.0.0.1'),
            'port' =&amp;gt; env('DB_PORT', '3306'),
            'database' =&amp;gt; 'database1',
            'username' =&amp;gt; env('DB_USERNAME', 'root'),
            'password' =&amp;gt; env('DB_PASSWORD', ''),
            'unix_socket' =&amp;gt; env('DB_SOCKET', ''),
            'charset' =&amp;gt; 'utf8mb4',
            'collation' =&amp;gt; 'utf8mb4_unicode_ci',
            'prefix' =&amp;gt; '',
            'prefix_indexes' =&amp;gt; true,
            'strict' =&amp;gt; true,
            'engine' =&amp;gt; null,
            'options' =&amp;gt; extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA =&amp;gt; env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you need to store the name of the database somewhere on your main database to call every time this client requests its instance via &lt;code&gt;ModelName::connection($databaseName)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This process will result in having one big giant &lt;code&gt;config/database.php&lt;/code&gt; if you have for example more than 100 clients. And it is kind of tedious to repeat every time you have a new client.&lt;/p&gt;

&lt;p&gt;You could make a script that automatically adds the client's database required config in &lt;code&gt;config/database.php&lt;/code&gt; but this won't make your file less big.&lt;/p&gt;

&lt;p&gt;The solution we came out with is simple and straightforward. All you need to do is create a table on your main database where you will define every client and their database name. Create a script either using PHP and a web interface or use a custom &lt;code&gt;Artisan&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;The custom &lt;code&gt;Artisan&lt;/code&gt; command will store the client in the main database (which is the only database defined on &lt;code&gt;config/database.php&lt;/code&gt;), create the client database and finally migrate all migrations. All of that using only one simple &lt;code&gt;artisan&lt;/code&gt; command line. Something like &lt;code&gt;php artisan client:make Client1&lt;/code&gt;. The name of the database will be &lt;code&gt;Client1&lt;/code&gt; in this case.&lt;/p&gt;

&lt;p&gt;Then instead of calling &lt;code&gt;ModelName::connection($clientDatabaseName)&lt;/code&gt;, you create a Trait where you will define the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$clientDatabaseName = MainDatabase::where('client_name', $request-&amp;gt;client_name)-&amp;gt;value('database_name');

config(['database.connections.mysql.database' =&amp;gt; $clientDatabaseName]);

\DB::purge('mysql');

\DB::reconnect('mysql');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To use this Trait either you call it on your models or you use it inside &lt;code&gt;AppServiceProvider&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Using this simple approach you won't need to store everything inside &lt;code&gt;config/database.php&lt;/code&gt; and you won't have to use &lt;code&gt;connection($db)&lt;/code&gt; every time you need to instantiate a &lt;code&gt;Model&lt;/code&gt;. Only with a simple &lt;code&gt;artisan&lt;/code&gt; command line, you take care of creating the database and its migrations and seeders if you have any.&lt;/p&gt;

&lt;p&gt;I hope this flash article helps, I would like to know in the comments how would you solve this.&lt;/p&gt;

&lt;p&gt;If you'd like me to create a full series of how to implement this approach, leave that in the comments section.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

&lt;p&gt;Cover image credit: &lt;a href="https://www.vecteezy.com/members/lavarmsg"&gt;lavarmsg&lt;/a&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>database</category>
      <category>performance</category>
    </item>
    <item>
      <title>Laravel: Softdelete Eloquent Relationships onDelete Cascade</title>
      <dc:creator>WAIYL KARIM</dc:creator>
      <pubDate>Fri, 10 Jul 2020 01:07:15 +0000</pubDate>
      <link>https://dev.to/waiylkarim/laravel-softdelete-eloquent-relationships-ondelete-cascade-36eo</link>
      <guid>https://dev.to/waiylkarim/laravel-softdelete-eloquent-relationships-ondelete-cascade-36eo</guid>
      <description>&lt;p&gt;Eloquent is one of many Laravel features that you just can't deny how cool and useful they are. However, sometimes even the very best things have their flaws. And one of Eloquent's is not being able to autodelete related objects through &lt;code&gt;SoftDelete&lt;/code&gt; when a model has a relationship to another with &lt;code&gt;onDelete('cascade')&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For this article, I am supposing that you are using &lt;code&gt;Laravel 5&lt;/code&gt;. So let's say you have your default &lt;code&gt;users&lt;/code&gt; table related to the &lt;code&gt;User&lt;/code&gt; model and you have another table called &lt;code&gt;invoices&lt;/code&gt; which is related to the &lt;code&gt;Invoice&lt;/code&gt; model. &lt;code&gt;User&lt;/code&gt; and &lt;code&gt;Invoice&lt;/code&gt; are linked through an Eloquent relationship as followed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// app/User.php
&amp;lt;?php

namespace App;

class User extends Authenticatable {

    // ...

    public function invoices() {
        return $this-&amp;gt;hasMany(Invoice::class);
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I think the code above does not need any explanations. It's a simple Eloquent relationship linking &lt;code&gt;User&lt;/code&gt; and &lt;code&gt;Invoice&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// app/User.php

&amp;lt;?php

namespace App;

class User extends Model {

    // ...

    /**
     * Holds the methods' names of Eloquent Relations 
     * to fall on delete cascade or on restoring
     * 
     * @var array
     */
    protected static $relations_to_cascade = ['invoices']; 

    protected static function boot()
    {
        parent::boot();

        static::deleting(function($resource) {
            foreach (static::$relations_to_cascade as $relation) {
                foreach ($resource-&amp;gt;{$relation}()-&amp;gt;get() as $item) {
                    $item-&amp;gt;delete();
                }
            }
        });

        static::restoring(function($resource) {
            foreach (static::$relations_to_cascade as $relation) {
                foreach ($resource-&amp;gt;{$relation}()-&amp;gt;get() as $item) {
                    $item-&amp;gt;withTrashed()-&amp;gt;restore();
                }
            }
        });
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's now break down this code:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;protected static $relations_to_cascade = ['invoices'];&lt;/code&gt; in this array we store the methods' names or relationships we wish to delete (or restore) when a &lt;code&gt;SoftDelete&lt;/code&gt; occurs. If we have more than one relationship, we should push them to the array. For instance:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;protected static $relations_to_cascade = ['invoices', 'roles'];&lt;/code&gt; &lt;em&gt;Note that we must have a &lt;code&gt;roles()&lt;/code&gt; relationship declared in our &lt;code&gt;Invoice&lt;/code&gt; model as well in this case or our app won't recognize the &lt;code&gt;roles&lt;/code&gt; method later on the code.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now that we have defined the Eloquent relationships we want deleted/restored we move on to actually deleting them and/or restoring them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        static::deleting(function($resource) {
            foreach (static::$relations_to_cascade as $relation) {
                foreach ($resource-&amp;gt;{$relation}()-&amp;gt;get() as $item) {
                    $item-&amp;gt;delete();
                }
            }
        });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This piece of code calls the &lt;code&gt;deleting&lt;/code&gt; method. Inside this method, We loop through our &lt;code&gt;$relations_to_cascade&lt;/code&gt; array. We then get all the concerned items from our database and delete them.&lt;/p&gt;

&lt;p&gt;Now once you understand this process, the next block will make sense&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
        static::restoring(function($resource) {
            foreach (static::$relations_to_cascade as $relation) {
                foreach ($resource-&amp;gt;{$relation}()-&amp;gt;get() as $item) {
                    $item-&amp;gt;withTrashed()-&amp;gt;restore();
                }
            }
        });

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yes exactly, it does the same thing but this time retrieves the concerned item &lt;code&gt;withTrashed()&lt;/code&gt; (because it was deleted and must include trashed items, duh!) and finally restore the item.&lt;/p&gt;

&lt;p&gt;And &lt;em&gt;voilà, c'est fait!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You can repeat the same logic for other models and other relationships. &lt;/p&gt;

&lt;p&gt;If you are starting a new Laravel project, it would be a good idea to keep this in mind and apply this paradigm with every model you create in order not to have to get back and change every model of your code — things can get messy, and trust me they will!&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
