One place for hosting & domains

      Eloquent

      How To Insert New Database Records in Laravel Eloquent



      Part of the Series:
      A Practical Introduction to Laravel Eloquent ORM

      Eloquent is an object relational mapper (ORM) that is included by default within the Laravel framework. In this project-based series, you’ll learn how to make database queries and how to work with relationships in Laravel Eloquent. To practice the examples explained throughout the series, you’ll improve a demo application with new models and relationships.

      In a previous section of this series, you set up two models for a one-to-many relationship between the LinkList and Link models. In this section, you’ll learn how to insert links and lists in the database using Eloquent models. To limit the scope of this work, you’ll use custom Artisan commands to manage links and lists from the command line, which won’t require a web form.

      One of the biggest advantages of using an ORM system is the ability to manipulate rows in a database table as objects within your codebase. With Eloquent, as with other ORMs, the object itself provides methods that can be used to persist it to the database, saving you the work of writing SQL statements and manually managing data within tables.

      When working with one-to-many relationships in Laravel Eloquent, you have a few different options to save related models. In most cases, you’ll need to first set up the model representing the one side of the relationship, which in this demo is the LinkList model, and save that to the database. After doing that, you’ll be able to reference this model (which, once saved, represents a database record) when setting up the many side of the relationship (the Link model). That also means you’ll need to first have one or more lists in order to be able to create links.

      Before creating a new command to insert lists, however, you should update the existing link:new command to support the list feature.

      Open the following file in your code editor:

      app/Console/Commands/LinkNew.php
      

      You’ll see code like this:

      app/Console/Commands/LinkNew.php

      <?php
      
      namespace AppConsoleCommands;
      
      use AppModelsLink;
      use IlluminateConsoleCommand;
      use IlluminateSupportFacadesDB;
      
      class LinkNew extends Command
      {
          /**
           * The name and signature of the console command.
           *
           * @var string
           */
          protected $signature="link:new";
      
          /**
           * The console command description.
           *
           * @var string
           */
          protected $description = 'Create a New Link';
      
          /**
           * Create a new command instance.
           *
           * @return void
           */
          public function __construct()
          {
              parent::__construct();
          }
      
          /**
           * Execute the console command.
           *
           * @return int
           */
          public function handle()
          {
              $url = $this->ask('Link URL:');
      
              if (!filter_var($url, FILTER_VALIDATE_URL)) {
                  $this->error("Invalid URL. Exiting...");
                  return 1;
              }
      
              $description = $this->ask('Link Description:');
      
              $this->info("New Link:");
              $this->info($url . ' - ' . $description);
      
              if ($this->confirm('Is this information correct?')) {
                  $link = new Link();
                  $link->url = $url;
                  $link->description = $description;
                  $link->save();
      
                  $this->info("Saved.");
              }
      
              return 0;
          }
      }
      
      

      The handle() method is where the command executes its procedures. This is what it does:

      1. The ask() method, made available through the parent IlluminateConsoleCommand class, is a method used to obtain input from a user in the command line. This will prompt a user for a link, and validate the input to make sure it’s a valid URL.
      2. The script then asks for an optional description.
      3. Once values for url and description are obtained, the script will prompt for a confirmation using the confirm() method, available through the parent IlluminateConsoleCommand.
      4. When a confirmation is submitted with y or yes, the script will set up a new link object and save it to the database using the save() method, available through the model’s parent IlluminateDatabaseEloquentModel class.
      5. The script outputs a message to inform the user that the link was saved to the database, using the info output method.

      Note about return values: in the context of command line applications running on bash, non-zero return values are used to signal that the application exited in error, while 0 means it exited with success.

      If you run the link:new command now, it will break before it is finished because the database expects every link to be connected to a list. You’ll need to let the user choose which list a link should be included in, using a default list if none is provided by the user.

      The following code will ask the user to specify a list or leave it blank to use the default list. Then, it will try to locate the list or create a new list using the specified slug in case the list doesn’t exist yet. To retrieve a list provided by the user, this code uses the firstWhere method to find a list based on its slug field. Finally, it saves the new link using the links() relationship that can be accessed from the LinkList object.

      Substitute the current content in your LinkNew command class with:

      app/Console/Commands/LinkNew.php

      <?php
      
      namespace AppConsoleCommands;
      
      use AppModelsLink;
      use AppModelsLinkList;
      use IlluminateConsoleCommand;
      use IlluminateSupportFacadesDB;
      
      class LinkNew extends Command
      {
          /**
           * The name and signature of the console command.
           *
           * @var string
           */
          protected $signature="link:new";
      
          /**
           * The console command description.
           *
           * @var string
           */
          protected $description = 'Create a New Link';
      
          /**
           * Create a new command instance.
           *
           * @return void
           */
          public function __construct()
          {
              parent::__construct();
          }
      
          /**
           * Execute the console command.
           *
           * @return int
           */
          public function handle()
          {
              $url = $this->ask('Link URL');
      
              if (!filter_var($url, FILTER_VALIDATE_URL)) {
                  $this->error("Invalid URL. Exiting...");
                  return 1;
              }
      
              $description = $this->ask('Link Description');
              $list_name = $this->ask('Link List (leave blank to use default)') ?? "default";
      
              $this->info("New Link:");
              $this->info($url . ' - ' . $description);
              $this->info("Listed in: " . $list_name);
      
              if ($this->confirm('Is this information correct?')) {
                  $list = LinkList::firstWhere('slug', $list_name);
                  if (!$list) {
                      $list = new LinkList();
                      $list->title = $list_name;
                      $list->slug = $list_name;
                      $list->save();
                  }
      
                  $link = new Link();
                  $link->url = $url;
                  $link->description = $description;
                  $list->links()->save($link);
      
                  $this->info("Saved.");
              }
      
              return 0;
          }
      }
      
      

      Save and close the file when you’re done. Then, run the command with:

      • docker-compose exec app php artisan link:new

      You’ll be prompted to provide a URL, a description, and a list name, in case you don’t want to save this link to the default list.

      Once you save your new link, if you run the link:show command, you should see the new link added to the results. However, there is no information included in the output about lists yet. You’ll need to update the LinkShow command to include a column that displays this information.

      Open the app/Console/Commands/LinkShow.php file in your code editor:

      app/Console/Commands/LinkShow.php
      

      This is how the class should look like now:

      app/Console/Commands/LinkShow.php

      <?php
      
      namespace AppConsoleCommands;
      
      use AppModelsLink;
      use IlluminateConsoleCommand;
      
      class LinkShow extends Command
      {
          /**
           * The name and signature of the console command.
           *
           * @var string
           */
          protected $signature="link:show";
      
          /**
           * The console command description.
           *
           * @var string
           */
          protected $description = 'List links saved in the database';
      
          /**
           * Create a new command instance.
           *
           * @return void
           */
          public function __construct()
          {
              parent::__construct();
          }
      
          /**
           * Execute the console command.
           *
           * @return int
           */
          public function handle()
          {
              $headers = [ 'id', 'url', 'description' ];
              $links = Link::all(['id', 'url', 'description'])->toArray();
              $this->table($headers, $links);
      
              return 0;
          }
      }
      

      You’ll see that the current handle() method is fetching a certain number of fields and converting the result to an array. By default, results come from Eloquent as an Eloquent Collection, so this function converts them to an array in order to use that data within the table() method. The problem is that when the array conversion is made, you lose the relationship between class models (Link and LinkList), which makes it more difficult to access information about the list that a link is connected to.

      You’ll need to change this code so that it fetches the full Link object, including the related objects from the database. To create an array that is suitable for using with the table() method, you can iterate through the collection of results returned by Link::all().

      Replace the current contents in the app/Console/Commands/LinkShow.php file with the following code:

      app/Console/Commands/LinkShow.php

      <?php
      
      namespace AppConsoleCommands;
      
      use AppModelsLink;
      use IlluminateConsoleCommand;
      
      class LinkShow extends Command
      {
          /**
           * The name and signature of the console command.
           *
           * @var string
           */
          protected $signature="link:show";
      
          /**
           * The console command description.
           *
           * @var string
           */
          protected $description = 'List links saved in the database';
      
          /**
           * Create a new command instance.
           *
           * @return void
           */
          public function __construct()
          {
              parent::__construct();
          }
      
          /**
           * Execute the console command.
           *
           * @return int
           */
          public function handle()
          {
              $headers = [ 'id', 'url', 'list', 'description' ];
              $links = Link::all();
      
              $table_rows = [];
              foreach ($links as $link) {
                  $table_rows[] = [ $link->id, $link->url, $link->link_list->slug, $link->description ];
              }
      
              $this->table($headers, $table_rows);
      
              return 0;
          }
      }
      
      

      Now, if you run the link:show method, you’ll see an additional column showing the list slug:

      Output

      +----+-----------------------------------------------------------------------------------------+-----------+--------------------------------------+ | id | url | list | description | +----+-----------------------------------------------------------------------------------------+-----------+--------------------------------------+ | 1 | https://digitalocean.com | default | DigitalOcean Website | | 2 | https://digitalocean.com/community/tutorials | tutorials | DO Tutorials | | 3 | https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-20-04 | tutorials | Initial server setup on ubuntu 20.04 | +----+-----------------------------------------------------------------------------------------+-----------+--------------------------------------+

      Later in this tutorial series, you’ll update the front end and main route code to show links organized into lists. For now, you’ll use the command line to add, migrate, and validate your changes to the database and models.

      The next tutorial in this series will demonstrate another way of inserting new records in the database using Eloquent models, this time through the use of database seeders.

      This tutorial is part of an ongoing weekly series about Laravel Eloquent. You can subscribe to the Laravel tag if you want to be notified when new tutorials are published.



      Source link

      How To Create a One-To-Many Relationship in Laravel Eloquent



      Part of the Series:
      A Practical Introduction to Laravel Eloquent ORM

      Eloquent is an object relational mapper (ORM) that is included by default within the Laravel framework. In this project-based series, you’ll learn how to make database queries and how to work with relationships in Laravel Eloquent. To practice the examples explained throughout the series, you’ll improve a demo application with new models and relationships.

      The demo Landing Laravel application that you set up as a prerequisite for this series contains a single database table to store links. In this tutorial you’ll modify this initial database structure to include a second table, which you will use to organize links into lists.

      For the links and lists example we’re going to use in this series, each link is part of only one list, but each list can have multiple links. This kind of relationship is also known as a one-to-many relationship.

      A one-to-many relationship happens when one item, which we’ll call type A, can be linked to several items of type B, but the opposite doesn’t hold true: an item of type B can only be linked to one item of type A. Transposing this scenario to the current demo application models, A is the list type, and B is the link type.

      To get started, you’ll need to create a model and a database table to represent a List of links. Then, you’ll update the existing Link model and table to include the relationship between both models. Because the term List is reserved for PHP internals, you won’t be able to name your new model with that term. You can call this new model LinkList instead.

      First, make sure you’re in the application directory:

      Create a new model using artisan:

      • docker-compose exec app php artisan make:model LinkList

      This will generate a new model class in the app/Model directory:

      app/Model/LinkList.php
      

      If you look at your app/Console/Commands directory, you’ll notice that there’s already a class file named LinkList.php. This is not to be confused with the Eloquent model you just created. This class contains a CLI command that lists all the links in the database via artisan.

      To avoid confusion in the future, now is a good moment to rename that class and its command signature to a different name. In this case use the class name LinkShow since that name also describes what the class does. To rename the app/Console/Commands/LinkList.php file to another valid name, run this command in your terminal:

      • mv app/Console/Commands/LinkList.php app/Console/Commands/LinkShow.php

      Then, open the file app/Console/Commands/LinkShow.php in your code editor to change the class name from LinkList to LinkShow, and the command signature from link:list to link:show, like the highlighted lines in the following code listing. This is how the file should look like once you’re finished:

      app/Console/Commands/LinkShow.php

      <?php
      
      namespace AppConsoleCommands;
      
      use AppModelsLink;
      use IlluminateConsoleCommand;
      
      class LinkShow extends Command
      {
          /**
           * The name and signature of the console command.
           *
           * @var string
           */
          protected $signature = 'link:show';
      
          /**
           * The console command description.
           *
           * @var string
           */
          protected $description = 'List links saved in the database';
      
          /**
           * Create a new command instance.
           *
           * @return void
           */
          public function __construct()
          {
              parent::__construct();
          }
      
          /**
           * Execute the console command.
           *
           * @return int
           */
          public function handle()
          {
              $headers = [ 'id', 'url', 'description' ];
              $links = Link::all(['id', 'url', 'description'])->toArray();
              $this->table($headers, $links);
      
              return 0;
          }
      }
      

      Save and close the file when you’re done. To check that everything worked as expected, run your newly renamed link:show artisan command:

      • docker-compose exec app php artisan link:show

      You’ll receive output like this:

      Output

      +----+-------------------------------------------------+----------------------------------+ | id | url | description | +----+-------------------------------------------------+----------------------------------+ | 1 | https://digitalocean.com/community | DigitalOcean Community | | 2 | https://digitalocean.com/community/tags/laravel | Laravel Tutorias at DigitalOcean | | 3 | https://digitalocean.com/community/tags/php | PHP Tutorials at DigitalOcean | +----+-------------------------------------------------+----------------------------------+

      The new app/Model/LinkList.php class that you generated with the previous artisan make:model command contains generic code for a new Eloquent class. Unlike other ORMs such as Doctrine, Eloquent doesn’t alter database structures, handling only data itself. Eloquent models are usually lean, with class properties automatically inferred from the model’s table structure.

      This approach to handling data-only with Eloquent means that you don’t need to set up any properties for the LinkList class because they will be inferred from the database table structure for that model.

      Structural database operations are typically handled in Laravel via database migrations. Migrations allow developers to programmatically define structural changes to the database, such as creating, modifying, and deleting tables.

      You’ll now create a new migration to set up the lists table in the database.

      The artisan command line tool included by default with Laravel contains several helper methods to bootstrap new components such as controllers, models, migrations, among others. To create a new migration using artisan, run:

      • docker-compose exec app php artisan make:migration create_link_lists_table

      Output

      Created Migration: 2021_07_07_152554_create_link_lists_table

      This command will generate a new file under the database/migrations directory in your Laravel application, using an auto-generated name based on the current date and time, and the migration name. That file contains generic code that you’ll modify to set up the lists table.

      Using your code editor, open the generated migration file. The file currently looks like this:

      database/migrations/2021_07_07_152554_create_link_lists_table.php

      <?php
      
      use IlluminateDatabaseMigrationsMigration;
      use IlluminateDatabaseSchemaBlueprint;
      use IlluminateSupportFacadesSchema;
      
      class CreateLinkListsTable extends Migration
      {
          /**
           * Run the migrations.
           *
           * @return void
           */
          public function up()
          {
              Schema::create('link_lists', function (Blueprint $table) {
                  $table->id();
                  $table->timestamps();
              });
          }
      
          /**
           * Reverse the migrations.
           *
           * @return void
           */
          public function down()
          {
              Schema::dropIfExists('link_lists');
          }
      }
      
      

      The migration runs the up() method when executed with the artisan migrate command. This is where your table definition goes, and by default it creates an id primary key field and two timestamp fields (created_at and updated_at), defined with the timestamps() Schema method. Those fields are automatically filled by Eloquent when a model is created and updated, respectively. The down() method is called when the migration is rolled back with the artisan rollback command, and typically executes code to drop the table or revert structural changes.

      You’ll change the up method to include the following fields:

      • title: a string representing the title of this List
      • description: a string representing the description of a List
      • slug: a unique, short string based on the title, typically used to create user-friendly URLs

      In a one-to-many relationship, the many side (which in this scenario corresponds to the links table) is the one to hold the column reference (or foreign key) to the other element (corresponding to the lists table). That means you’ll have to modify the links table later on, in order to include a reference field that will link that table to the lists table.

      The lists table, on the other hand, doesn’t need any special field to reference its links.

      Replace the current content in your migration file with the following code:

      database/migrations/2021_07_07_152554_create_link_lists_table.php

      <?php
      
      use IlluminateDatabaseMigrationsMigration;
      use IlluminateDatabaseSchemaBlueprint;
      use IlluminateSupportFacadesSchema;
      
      class CreateLinkListsTable extends Migration
      {
          /**
           * Run the migrations.
           *
           * @return void
           */
          public function up()
          {
              Schema::create('link_lists', function (Blueprint $table) {
                  $table->id();
                  $table->timestamps();
                  $table->string('title', 60);
                  $table->string('slug', 60)->unique();
                  $table->text('description')->nullable();
              });
          }
      
          /**
           * Reverse the migrations.
           *
           * @return void
           */
          public function down()
          {
              Schema::dropIfExists('link_lists');
          }
      }
      
      

      Save the file when you’re done.

      Next, open the existing links migration file in your code editor. In the demo project, you’ll find the migration at the following path:

      2020_11_18_165241_create_links_table.php
      

      First, include a use directive pointing to the fully qualified class name for the LinkList class, at the beginning of the file and right after the last use line:

      …
      use IlluminateSupportFacadesSchema;
      use AppModelsLinkList;
      ...
      

      Next, include the following line in the table definition, within the up method and right after the line that sets up the description field:

      $table->text('description');
      $table->foreignIdFor(LinkList::class);
      

      The foreignIdFor() method creates a foreign key column to the referenced Eloquent model. It uses default nomenclature to set up a field that is linked to the primary key field of the referenced table.

      This is how the full migration class should look like when you’re done:

      database/migrations/2020_11_18_165241_create_links_table.php

      <?php
      
      use IlluminateDatabaseMigrationsMigration;
      use IlluminateDatabaseSchemaBlueprint;
      use IlluminateSupportFacadesSchema;
      use AppModelsLinkList;
      
      class CreateLinksTable extends Migration
      {
          /**
           * Run the migrations.
           *
           * @return void
           */
          public function up()
          {
              Schema::create('links', function (Blueprint $table) {
                  $table->id();
                  $table->string('url', 200);
                  $table->text('description');
                  $table->foreignIdFor(LinkList::class);
                  $table->timestamps();
              });
          }
      
          /**
           * Reverse the migrations.
           *
           * @return void
           */
          public function down()
          {
              Schema::dropIfExists('links');
          }
      }
      

      Save the file when you’re finished editing it. Next, wipe the database and then run the migration command again to recreate your database structure with the updated migrations files:

      • docker-compose exec app php artisan db:wipe
      • docker-compose exec app php artisan migrate

      Configuring Eloquent Model Relationships

      The database tables are now set up, but you still need to configure the Eloquent models to define the relationship between them.

      On the List model, which is the one side of the relationship, you’ll set up a new method named links. This method will work as a proxy to access the links that are related to each list, using the hasMany method from the parent IlluminateDatabaseEloquentModel class.

      In your code editor, open the file app/Model/LinkList.php. Replace the current generic code with the following content:

      app/Model/LinkList.php

      <?php
      
      namespace AppModels;
      
      use IlluminateDatabaseEloquentFactoriesHasFactory;
      use IlluminateDatabaseEloquentModel;
      
      class LinkList extends Model
      {
          use HasFactory;
      
          public function links()
          {
              return $this->hasMany(Link::class);
          }
      }
      
      

      Save the file when you’re done.

      Next, you’ll edit the many side of the relationship to include a reference back to the List model, so that links can access their respective list. This is done with the belongsTo method from the parent Model class. This method is used to define the inverse side of the one-to-many relationship.

      Open the Link model in your code editor:

      app/Model/Link.php
      

      Replace the current content in your Link.php file with the following code:

      app/Model/Link.php

      <?php
      
      namespace AppModels;
      
      use IlluminateDatabaseEloquentModel;
      
      class Link extends Model
      {
          public function link_list()
          {
              return $this->belongsTo(LinkList::class);
          }
      }
      
      

      Save the file when you’re done.

      With both models updated, your database is now configured completely, but it is currently empty. In the next section of this series, you’ll learn how to insert new records in the database using Eloquent models.

      This tutorial is part of an ongoing weekly series about Laravel Eloquent. You can subscribe to the Laravel tag if you want to be notified when new tutorials are published.



      Source link

      How To Create a Database Model in Laravel with Eloquent



      Part of the Series:
      How To Build a Links Landing Page in PHP with Laravel and Docker Compose

      Laravel is an open-source PHP framework that provides a set of tools and resources to build modern PHP applications. In this project-based tutorial series, you’ll build a Links Landing Page application with the Laravel framework, using a containerized PHP development environment managed by Docker Compose.

      At the end, you’ll have a one-page website built with Laravel and managed via Artisan commands where you can share relevant links to an audience on social channels and presentations.

      Eloquent is an object relational mapper (ORM) included by default within the Laravel framework. It facilitates the task of interacting with database tables, providing an object-oriented approach to inserting, updating, and deleting database records, while also providing a streamlined interface for executing SQL queries.

      Eloquent uses database models to represent tables and relationships in supported databases. The name of the database table is typically inferred from the model name, in plural form. For instance, a model named Link will use links as its default table name.

      You can use the artisan make:model command line helper to generate new models for your application. To create a new Eloquent model for your links table, run:

      • docker-compose exec app php artisan make:model Link

      Output

      Model created successfully.

      This will generate a new file containing a barebones model class. Even though this class has no apparent properties or methods, when operating the model via facades, you have access to the underlying Eloquent database classes that are able to identify database table structures and represent them as fully-functional objects.

      For your reference, this is the automatically generated model class:

      app/Models/Link.php

      <?php
      
      namespace AppModels;
      
      use IlluminateDatabaseEloquentFactoriesHasFactory;
      use IlluminateDatabaseEloquentModel;
      
      class Link extends Model
      {
          use HasFactory;
      }
      
      

      For the purpose of this series, you don’t need to make any changes to this file. If you want to extend the application in the future, you might use this model to create custom methods for the Link class that involve database operations. Additionally, if you want to create relationships between the Link model and other models, you’ll need to include a method representing the relationship in at least one of the sides. For detailed information about Eloquent relationships, please refer to the official documentation.

      In the next part of this series, you’ll create Artisan commands that will use this model to select, insert, and delete links on your database.



      Source link