Why does php artisan create migration class with empty up method? - php

I am currently learning from this video
https://laracasts.com/series/laravel-from-scratch-2018/episodes/7
about database migrations in laravel.
I typed in console :
php artisan make:migration create_projects_table
just like the teacher in the video and somehow I get an empty method definition in the migrations folder.
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateProjectsTable extends Migration
{
public function up()
{
//should contain Schema::create but it is empty
}
public function down()
{
}
}
What did I do wrong? I followed all those instructions in the video.

You can specify the table:
php artisan make:migration create_projects_table --create=projects
edit: It should indeed work without adding the argument:
https://github.com/laravel/framework/blob/854e6d1d001f5e9a6d1376d2284eaa99b0c1e443/src/Illuminate/Database/Console/Migrations/MigrateMakeCommand.php#L88
// Next, we will attempt to guess the table name if this the migration has
// "create" in the name. This will allow us to provide a convenient way
// of creating migrations that create new tables for the application.
if (! $table) {
[$table, $create] = TableGuesser::guess($name);
}
The tableGuesser class
Here you can see that your tables name should match (\w+) pattern

Use this command on root folder
php artisan make:migration create_projects_table --create=projects //create only Migration file
php artisan make:model Project -m //Create Migration, Model file
php artisan make:model Project -mcr //For Create Migration,Model,Controller file

Related

php artisan make:migration not creaing new table

I have a table in my db named affilaite.
But when i try to create a new table named as product it gives me an error
php artisan make:migration create_product_table
PHP Fatal error: Cannot declare class CreateAffiliateTable, because the name is already in use in /home/manak/Desktop/manu/Edolve/database/migrations/2021_03_09_063908_create_affiliate_table.php on line 7
Symfony\Component\ErrorHandler\Error\FatalError
Cannot declare class CreateAffiliateTable, because the name is already in use
at database/migrations/2021_03_09_063908_create_affiliate_table.php:7
3▕ use Illuminate\Database\Migrations\Migration;
4▕ use Illuminate\Database\Schema\Blueprint;
5▕ use Illuminate\Support\Facades\Schema;
6▕
➜ 7▕ class CreateAffiliateTable extends Migration
8▕ {
9▕
10▕ Run the migrations.
11▕
Whoops\Exception\ErrorException
Cannot declare class CreateAffiliateTable, because the name is already in use
at database/migrations/2021_03_09_063908_create_affiliate_table.php:7
3▕ use Illuminate\Database\Migrations\Migration;
4▕ use Illuminate\Database\Schema\Blueprint;
5▕ use Illuminate\Support\Facades\Schema;
6▕
➜ 7▕ class CreateAffiliateTable extends Migration
8▕ {
9▕
10▕ Run the migrations.
11▕
+1 vendor frames
2 [internal]:0
Whoops\Run::handleShutdown()
From This error I Think U already have A migration named CreateAffiliateTable.
Please Change Your Migration name or Delete the Old migration
Check your database/migration folder. if a file already prosent there remove it. Also if there is already a table named exactly the same drop that table from database. Also in database there is a migrations table. Delete the tablename from there also and try migrating again.
By laravel convention migrations are plural and model name singular. So better try CreateAffiliatesTable instead of CreateAffiliateTable
use this command for create
$ php artisan make:migration create_products_table

Laravel Models Defining Columns Possible?

I just started playing with Laravel, and was wondering the following:
Can you define your table structure in the model, then create a migration based off it? (The way Django works).
namespace App;
use Illuminate\Database\Eloquent\Model;
class SomeListing extends Model
{
// Below V V V V Define Columns
public $title = ''; // somehow make a string(255)?
public $description = ''; // somehow make a text?
// etc
// etc
}
Or must you always adjust the migration files? I could not find this here.
I think it does not exist, but you can create migrations for your database with migrations
Create migration
php artisan make:migration create_table_name
and
php artisan migrate
More info could be found at Laravel's Migration Document

How to run laravel migration and DB seeder except one

I am having many migration and seeder files to run, Although I will need to run all files but currently I need to skip one migration and seeder.
How could I skip one file from laravel migration and db seeder command.
I do not want to delete files from the migrations or seeds folder to skip the file.
Laravel doesn't give you a default method to do it. However, you can create your own console commands and seeder to achieve it.
Let's say you have this default DatabaseSeeder class:
class DatabaseSeeder extends Seeder
{
public function run()
{
$this->call(ExampleTableSeeder::class);
$this->call(UserSamplesTableSeeder::class);
}
}
the goal is to create a new command overriding "db:seed" and pass a new parameter, an "except" parameter, to the DatabaseSeeder class.
This is the final code, I created on my Laravel 5.2 instance and tried:
Command, put in app/Console/Commands, don't forget to update your Kernel.php:
namespace App\Console\Commands;
use Illuminate\Console\Command;
class SeedExcept extends Command
{
protected $signature = 'db:seed-except {--except=class name to jump}';
protected $description = 'Seed all except one';
public function handle()
{
$except = $this->option('except');
$seeder = new \DatabaseSeeder($except);
$seeder->run();
}
}
DatabaseSeeder
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
protected $except;
public function __construct($except = null) {
$this->except = $except;
}
public function call($class)
{
if ($class != $this->except)
{
echo "calling $class \n";
//parent::call($class); // uncomment this to execute after tests
}
}
public function run()
{
$this->call(ExampleTableSeeder::class);
$this->call(UserSamplesTableSeeder::class);
}
}
It the code, you'll find that I commented the line that calls the seed and added an echo for testing purposes.
Executing this command:
php artisan db:seed-except
will give you:
calling ExampleTableSeeder
calling UserSamplesTableSeeder
However, adding "except":
php artisan db:seed-except --except=ExampleTableSeeder
will give you
calling UserSamplesTableSeeder
This works overriding the default call method of your DatabaseSeeder class and calling the parent only if the name of the class is not in the $except variable. The variable is populated by the SeedExcept custom command.
Regarding migrations, the thing is similar but a little bit more difficult.
I can't give you tested code for this by now, but the thing is:
you create a migrate-except command that overrides the MigrateCommand class (namespace Illuminate\Database\Console\Migrations, located in vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/MigrateCommand.php).
the MigrateCommand takes a Migrator object (namespace Illuminate\Database\Migrations, path vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php) in the constructor (injected via IoC). The Migrator class owns the logic that reads all the migrations inside the folder and execute it. This logic is inside the run() method
create a subclass of Migrator, for example MyMigrator, and override the run() method to skip the files passed with the special option
override the __construct() method of your MigrateExceptCommand and pass your MyMigrator: public function __construct(MyMigrator $migrator)
If I have time I'll add the code for an example before the bounty ends
EDIT
as promised, here's an example for migrations:
MyMigrator class, extends Migrator and contains the logic to skip files:
namespace App\Helpers;
use Illuminate\Database\Migrations\Migrator;
class MyMigrator extends Migrator
{
public $except = null;
// run() method copied from it's superclass adding the skip logic
public function run($path, array $options = [])
{
$this->notes = [];
$files = $this->getMigrationFiles($path);
// skip logic
// remove file from array
if (isset($this->except))
{
$index = array_search($this->except,$files);
if($index !== FALSE){
unset($files[$index]);
}
}
var_dump($files); // debug
$ran = $this->repository->getRan();
$migrations = array_diff($files, $ran);
$this->requireFiles($path, $migrations);
//$this->runMigrationList($migrations, $options); // commented for debugging purposes
}
}
The MigrateExcept custom command
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Database\Console\Migrations\MigrateCommand;
use App\Helpers\MyMigrator;
use Illuminate\Database\Migrations\Migrator;
use Symfony\Component\Console\Input\InputOption;
class MigrateExcept extends MigrateCommand
{
protected $name = 'migrate-except';
public function __construct(MyMigrator $migrator)
{
parent::__construct($migrator);
}
public function fire()
{
// set the "except" param, containing the name of the file to skip, on our custom migrator
$this->migrator->except = $this->option('except');
parent::fire();
}
// add the 'except' option to the command
protected function getOptions()
{
return [
['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'],
['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production.'],
['path', null, InputOption::VALUE_OPTIONAL, 'The path of migrations files to be executed.'],
['pretend', null, InputOption::VALUE_NONE, 'Dump the SQL queries that would be run.'],
['seed', null, InputOption::VALUE_NONE, 'Indicates if the seed task should be re-run.'],
['step', null, InputOption::VALUE_NONE, 'Force the migrations to be run so they can be rolled back individually.'],
['except', null, InputOption::VALUE_OPTIONAL, 'Files to jump'],
];
}
}
Last, you need to add this to a service provider to permit the Laravel IoC resolve the dependencies
namespace App\Providers;
use App\Helpers\MyMigrator;
use App\Console\Commands\MigrateExcept;
class CustomServiceProvider extends ServiceProvider
{
public function boot()
{
parent::boot($events);
$this->app->bind('Illuminate\Database\Migrations\MigrationRepositoryInterface', 'migration.repository');
$this->app->bind('Illuminate\Database\ConnectionResolverInterface', 'Illuminate\Database\DatabaseManager');
$this->app->singleton('MyMigrator', function ($app) {
$repository = $app['migration.repository'];
return new MyMigrator($repository, $app['db'], $app['files']);
});
}
}
Don't forget to add Commands\MigrateExcept::class in the Kernel.php
Now, if you execute
php artisan migrate-except
you have:
array(70) {
[0] =>
string(43) "2014_04_24_110151_create_oauth_scopes_table"
[1] =>
string(43) "2014_04_24_110304_create_oauth_grants_table"
[2] =>
string(49) "2014_04_24_110403_create_oauth_grant_scopes_table"
...
but adding the except param:
php artisan migrate-except --except=2014_04_24_110151_create_oauth_scopes_table
array(69) {
[1] =>
string(43) "2014_04_24_110304_create_oauth_grants_table"
[2] =>
string(49) "2014_04_24_110403_create_oauth_grant_scopes_table"
So, recap:
we create a custom migrate-except command, MigrateExcept class, extending MigrateCommand
we create a custom migrator class, MyMigrator, extending the behavior of the standard Migrator
when MigrateExcept is fire(), pass the name of the file to skip to our MyMigrator class
MyMigrator overrides the run() method of Migrator and skip the passed migration
More: since we need to instruct Laravel IoC about the new created classes, so it can inject them correctly, we create a Service Provider
The code is tested so it should work correctly on Laravel 5.2 (hoping that cut&paste worked correctly :-) ...if anyone has any doubt leave a comment
Skipping seeds are very simple, migrations not so much. To skip a seed, remove the following from your DatabaseSeeder class.
$this->call(TableYouDontWantToSeed::class);
For migrations, There are three ways you can do it:
Put the class you don't want to migrate into a different folder.
Insert your migrations into the database manually (Bindesh Pandya's answer elaborated).
Rename the file that you don't want to migrate to something like UsersTableMigration.dud.
Hope this helps
I also faced the same problem in my project but after long time wasting in R & D i have found that Laravel does not provide any way to do this with migration and seeding but you have 2 ways to do this.
1) you'll save a lot of time just putting them into different folders.
You could theoretically make your own artisan command that does what
you want, or spoofs its by making directories, moving files, and running
php artisan migrate.
For the seeders, just make a seeder and call the others seeders you want to run from with in it. Then just be explicit about what seeder you want to run. Try php artisan db:seed --help for more details there.
2) you can create a table Manually (which has same name as migration table is creating in you db) and insert the values of migration like this
insert into migrations(migration, batch) values('2015_12_08_134409_create_tables_script',1);
so migrate command will not create table which is already exist in migration table.
If you want just omit (but keep) migration and seeder:
Rename your migration by removing .php extension: mv your_migration_file.php your_migration_file
Go to: DatabaseSeeder.php and comment out line with your unwanted seeder: //$this->call('YourSeeder');.
Run: php artisan migrate --seed
Execute below sql query on db (be careful, there should be migration file name WITHOUT extension) (this will prevent artisan migrate to execute your_migration_file in future):
INSERT INTO migrations (migration, batch) VALUES (your_migration_file, 1)
Rename back your migration file: mv your_migration_file your_migration_file.php
Uncomment your seeder in DatabaseSeeder.php
And you are done. Now when you run php artisan migrate any migration should be executed (except new one if you add some new migration files).
just an idea comment seeder and schema. this is the way i guess
//$this->call(HvAccountsSeeder::class);
//Schema::create('users', function (Blueprint $table) {
// $table->increments('id');
// $table->string('name');
// $table->string('email')->unique();
// $table->string('password');
// $table->rememberToken();
// $table->timestamps();
// });
// Schema::drop('users');
To directly answer your question, Laravel does not have a way to do this currently.
If I understand you correctly, I assume you're looking for a way to temporarily disable/skip a specific class from the default DatabaseSeeder.
You can easily create your own command which will accept a string such as a model/table name and attempt to run the migration and seed for that particular table. You will simply need something like the following:
public function handle(){ //fire for Laravel 4.*
$tables = explode(',', $this->option('tables'));//default []
$skip = explode(',', $this->option('skip'));//default []
$migrations = glob("*table*.php");//get all migrations
foreach($migrations as $migrate){
//if tables argument is set, check to see if part of tables
//if file name not like any in skip.. you get the point

Laravel 4 Migration Error

I'm getting the following error when trying to create migrations for my laravel 4 installation. The file gets created but it outputs the following error.
Created Migration: 2014_07_06_073213_create-users-table
Generating optimized class loader
Compiling common classes
{"error":
{"type":"Symfony\\Component\\Debug\\Exception\\FatalErrorException","message":"Class 'ClassPreloader\\Command\\PreCompileCommand' not found","file":"\/home\/name123\/domain.com\/laravel\/vendor\/laravel\/framework\/src\/Illuminate\/Foundation\/Console\/OptimizeCommand.php","line":113}}[warehouse]
$ php artisan migrate:make create-users-table
It doesn't seem that there are any other people having the same problem.
Also getting this error when i commit the migration
{"error":{"type":"Symfony\\Component\\Debug\\Exception\\FatalErrorException","message":"Call to a member function increments() on a non-object","file":"\/home\/dandel26\/danieldelcore.com\/laravel\/app\/database\/migrations\/2014_06_29_092641_create_users_table.php","line":15}}
Thanks in advance.
In you're migration you have the function up. In this function there will be something like:
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
});
It would seem that you did not do define the callback with the variable $table. Please add Blueprint $table and it should work.
In that case remember to import the right namespaces:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

How to have conditional database seeding in Laravel?

Can I create seed groups? For instance I have seeds that I only want executed some of the time. How can I add a flag when executing php artisan migrate --seed --group1
What are my options for such feature?
Well, what you could do is create multiple Seeder extended classes, and having each one of them running $this->call() on a specific group of tables and then specify which one you want using the --class flag. Something like this:
class GroupOneDatabaseSeeder extends Seeder {
public function run() {
Eloquent::unguard();
$this->call('UserTableSeeder');
$this->call('RoleTableSeeder');
}
}
And then call it this way:
php artisan db:seed --class="GroupOneDatabaseSeeder"
Well, that or you could extend the SeedCommand to add this functionality via methods instead of classes.

Categories