Viewed   111 times

My application needs a pre registered data set to work. So i need to insert them in the database when i set up the application.

Laravel propose two mechanisms :

  • Database migrations : "They allow a team to modify the database schema and stay up to date on the current schema state."
  • Database seeding : "Laravel also includes a simple way to seed your database with test data using seed classes."

When I read this description, none of these solutions seems to be adapted.

A similar question has been asked on and answered. The answer proposes to use the a database seeder to populate the database by detecting the current environment :

<?php

class DatabaseSeeder extends Seeder {

    public function run()
    {
            Eloquent::unguard();

            if (App::environment() === 'production')
            {
                $this->call('ProductionSeeder');
            }
            else
            {
                $this->call('StagingSeeder');
            }
    }

}

Of course, this solution works. But i am not sure that it is the right way to do this, because by inserting data using seeders you are losing all the advantages provided by the migration mechanism (database upgrate, rollback...)

I want to know what is the best practice in this case.

 Answers

1

Laravel development is about freedom. So, if you need to seed your production database and think DatabaseSeeder is the best place to do so, why not?

Okay, seeder is mainly to be used with test data, but you'll see some folks using it as you are.

I see this important kind of seed as part of my migration, since this is something that cannot be out of my database tables and artisan migrate is ran everytime I deploy a new version of my application, so I just do

php artisan migrate:make seed_models_table

And create my seedind stuff in it:

public function up()
{
    $models = array(
        array('name' => '...'),
    );

    DB::table('models')->insert($models);
}
Thursday, November 3, 2022
1

It turns out; when you create a foreign key like this:

$table->integer('pick_detail_id')->unsigned();
$table->foreign('pick_detail_id')->references('id')->on('pick_details');

Laravel uniquely names the foreign key reference like this:

<table_name>_<foreign_table_name>_<column_name>_foreign
despatch_discrepancies_pick_detail_id_foreign (in my case)

Therefore, when you want to drop a column with foreign key reference, you have to do it like this:

$table->dropForeign('despatch_discrepancies_pick_detail_id_foreign');
$table->dropColumn('pick_detail_id');

Update:

Laravel 4.2+ introduces a new naming convention:

<table_name>_<column_name>_foreign
Friday, September 9, 2022
 
5

Migrations are a type of version control for your database. They allow a team to modify the database schema and stay up to date on the current schema state. Migrations are typically paired with the Schema Builder to easily manage your application's schema.

With migrations you don't need to create table in phpMyAdmin, you can do it in Laravel. Here is an example to create a user table:

class CreateUsersTable extends Migration {

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function(Blueprint $table)
        {
            $table->increments('id'); // autoincrement id field
            $table->string('name');   // string field
            $table->string('lastname');
            $table->string('title');
            $table->string('email')->unique();   // unique string field
            $table->string('password', 60);      // string field with max 60 characters
            $table->boolean('Status')->default(0); // string field with default value 0
            $table->timestamps();

        });
    }


    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('users');
    }

}

I this code we create table with fields like "name", "lastname"... we said in our Laravel code they are string type when migration is done we have complete table in databese with this fields.

Run a migration to create table

To create a migration, you may use the make:migration command on the Artisan CLI (artisan command line interface):

php artisan make:migration create_users_table

or

php artisan make:migration create_users_table --create=users

Run a migration to alter table

When you need to do some changes in database table example: add field vote to user table you can do like this in your Laravel code without touching SQL code

php artisan make:migration add_votes_to_users_table --table=users

Rollback the last migration operation

If you make mistake and did something wrong you can always rollback to return database in previous state.

php artisan migrate:rollback

Rollback all migrations

php artisan migrate:reset

Rollback all migrations and run them all again

php artisan migrate:refresh

php artisan migrate:refresh --seed

One of best advantage of migrations are creating database without touching SQL code. You can make whole database with relationship in PHP code then migrate it into MySQL, PL/SQL, MSSQL or any other database.

Also I recommend the free Laravel 5 fundamental series, in episode 7 you can hear more about migrations.

Thursday, September 1, 2022
 
smn
 
smn
2

Drop foreign key first. Thanks to Razor for this tip

$table->dropForeign('answers_user_id_foreign');
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade');
Sunday, November 27, 2022
4

Use the migrate command

You can add the --pretend flag when you run php artisan migrate to output the queries to the terminal:

php artisan migrate --pretend

This will look something like this:

Migration table created successfully.
CreateUsersTable: create table "users" ("id" integer not null primary key autoincrement, "name" varchar not null, "email" varchar not null, "password" varchar not null, "remember_token" varchar null, "created_at" datetime not null, "updated_at" datetime not null)
CreateUsersTable: create unique index users_email_unique on "users" ("email")
CreatePasswordResetsTable: create table "password_resets" ("email" varchar not null, "token" varchar not null, "created_at" datetime not null)
CreatePasswordResetsTable: create index password_resets_email_index on "password_resets" ("email")
CreatePasswordResetsTable: create index password_resets_token_index on "password_resets" ("token")

To save this to a file, just redirect the output without ansi:

php artisan migrate --pretend --no-ansi > migrate.sql

This command only include the migrations that hasn't been migrated yet.


Hack the migrate command

To further customize how to get the queries, consider hacking the source and make your own custom command or something like that. To get you started, here is some quick code to get all the migrations.

Example code

$migrator = app('migrator');
$db = $migrator->resolveConnection(null);
$migrations = $migrator->getMigrationFiles('database/migrations');
$queries = [];

foreach($migrations as $migration) {
    $migration_name = $migration;
    $migration = $migrator->resolve($migration);

    $queries[] = [
        'name' => $migration_name,
        'queries' => array_column($db->pretend(function() use ($migration) { $migration->up(); }), 'query'),
    ];
}

dd($queries);

Example output

array:2 [
  0 => array:2 [
    "name" => "2014_10_12_000000_create_users_table"
    "queries" => array:2 [
      0 => "create table "users" ("id" integer not null primary key autoincrement, "name" varchar not null, "email" varchar not null, "password" varchar not null, "remember_token" varchar null, "created_at" datetime not null, "updated_at" datetime not null)"
      1 => "create unique index users_email_unique on "users" ("email")"
    ]
  ]
  1 => array:2 [
    "name" => "2014_10_12_100000_create_password_resets_table"
    "queries" => array:3 [
      0 => "create table "password_resets" ("email" varchar not null, "token" varchar not null, "created_at" datetime not null)"
      1 => "create index password_resets_email_index on "password_resets" ("email")"
      2 => "create index password_resets_token_index on "password_resets" ("token")"
    ]
  ]
]

This code will include all the migrations. To see how to only get what isn't already migrated take a look at the run() method in vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php.

Friday, December 16, 2022
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :