Seeding from a package / Fixing ReflectionException - laravel

I have created a package which copies migrations and seeds to the respective directories in the base app.
However, unless I call (add) these within the run() function in the DatabaseSeeder class in the base app (app/database/seeds/DatabaseSeeder.php) when I run
php artisan migrate:refresh --seed
Then the seeds are not run. How can I automate this part so the user doesn't have to manually edit this file? Are there any artisan commands to manually run seeds?

Still don't completely understand how I got this to work, but for others;
In your boot method of your PackagenameServiceProvider use $this->publishes() to move the seeds and migrations to the base app
public function boot()
{
if (!$this->app->routesAreCached()) {
require __DIR__.'/../routes.php';
}
$this->publishes([
__DIR__.'/../DatabaseStuff/Migrations' => $this->app->databasePath().'/migrations',
__DIR__.'/../DatabaseStuff/Seeds/Example1Seeder.php' => $this->app->databasePath().'/seeds/Example1Seeder.php',
__DIR__.'/../DatabaseStuff/Seeds/Example2Seeder.php' => $this->app->databasePath().'/seeds/Example2Seeder.php',
]);
}
Have a copy of DatabaseSeeder with call methods pointing to the seeds you wish to run but make sure it's name-spaced correctly to where ever you have the files in your package.
namespace ExampleVendor\ExamplePackage\DatabaseStuff;
use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
Model::unguard();
$this->call(\Example1Seeder::class);
$this->call(\Example2Seeder::class);
Model::reguard();
}
}
Now run the following commands. The critical command for me in this case was php artisan optimize
php artisan vendor:publish
composer dump-autoload
php artisan cache:clear
php artisan optimize
php artisan db:seed --class="ExampleVendor\ExamplePackage\DatabaseStuff\DatabaseSeeder"
Without php artisan optimize I kept getting
ReflectionException
Class ExampleVendor\ExamplePackage\DatabaseStuff\DatabaseSeeder does not exist
Hopefully this helps someone in the future.

Related

Run Laravel Seeder From Package

I'm working on a package for an internal Laravel application and I'm having trouble running a seeder that exists in the package directory.
In my package's composer.json file located in packages/vendor/packagename, I've added the following:
"autoload": {
"psr-4": {
"Vendor\\PackageName\\": "src/",
"Vendor\\PackageName\\Database\\Factories\\": "database/factories/",
"Vendor\\PackageName\\Database\\Seeders\\": "database/seeders/"
}
},
I have the following file located in "packages/vendor/packagename/database/seeders/DepartmentSeeder.php"
<?php
namespace Vendor\PackageName\Database\Seeders;
use Illuminate\Database\Seeder;
use Vendor\PackageName\Models\Department;
class DepartmentSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
Department::factory()->count(10)->create();
}
}
I then attempt to run the following command:
$ php artisan db:seed --class="Vendor\\PackageName\\Database\\Seeders\\DepartmentSeeder"
Target class [Vendor\PackageName\Database\Seeders\DepartmentSeeder] does not exist.
If I move the seeders directory into my src directory and run the following, it works, but I'd rather keep my seeders in my database directory.
$ php artisan db:seed --class="Vendor\\PackageName\\seeders\\DepartmentSeeder"
Does anyone have any idea why the class isn't being found? All my Google search results are purple and I even went to page two =/
Solution
In my particular case, composer dump-autoload wasn't doing the trick. What I ended up doing was running composer update vendor/packagename and whatever the issue was, it was resolved.
Hopefully, this helps anyone else who may have similar issues.
In my particular case, composer dump-autoload wasn't doing the trick. What I ended up doing was running composer update vendor/packagename and whatever the issue was, it was resolved.
Hopefully, this helps anyone else who may have similar issues.

Service Provider not booting in Laravel 5.8

I've created a new service provider to observe a model (App\Providers\EloquentEventServiceProvider.php), like so:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Staff;
use App\Oberservers\StaffObserver;
class EloquentEventServiceProvider extends ServiceProvider
{
public function boot()
{
Staff::observe(StaffObserver::class);
}
}
I've also added it to the config file (config\app.php):
return [
...
'providers' => [
...
App\Providers\EloquentEventServiceProvider::class,
...
]
...
]
The observer methods aren't working though. If I move Staff::observe(StaffObserver::class); to the AppServiceProvider class, it works just fine. So clearly this is an issue with getting my service provider to boot. I've tried php artisan config:clear, php artisan clear-compiled, composer update and composer dump but none have work. Any help is greatly aprpeciated.
your Oberservers name is wrong, as mentioned in the laravel doc observers laravel doc it should be Observers which means all of your observers should be within App\Observers instead of App\Oberservers.
so here we have 2 solutions :
1- if you want to keep the namespace App\Oberservers, you should run these 2 commands below because autoloading of the files may not work properly because we created a new folder Oberservers:
# Autoloading of files
composer dump
# Configure the cache
php artisan config:cache
2- the second solution is to just rename your actual Oberservers folder to Observers, in that way the autoloading of files will work well.

Laravel db:seed does not work without --class parameter

Running php artisan db:seed does not work for some reason on my Laravel 5.6 project.
The command runs (quietly) even without a database
Does not return any error on the terminal
However, when I run php artisan db:seed --class=ClassNameTableSeeder it works. What could be the cause of such a weird behavior?
NB : Similar to questions like 39521913 but not a duplicate.
This is because by default DatabaseSeeder does nothing. Original code in fresh Laravel project looks like this:
public function run()
{
// $this->call(UsersTableSeeder::class);
}
So to run any database seeder, you should uncomment this line and put valid class name, so for example:
$this->call(ClassNameTableSeeder1::class);
$this->call(ClassNameTableSeeder2::class);
and so on to run seeders for each class you put here.

Create single table using php artisan migrate

I have executed this command to create a 'Users' table:
php artisan migrate
But after that I have created one new migration file using below command and want to create a 'Contact us' table
php artisan make:migration contactus
After both commands whenever I execute below command for generating the 'Contact us' table i get the following error: Table 'users' already exists
php artisan migrate
This is my code of migration file Contactus :
public function up()
{
Schema::create('contactus',function(Blueprint $table){
$table->increments('id');
$table->string('email');
$table->string('message');
$table->timestamp('created_at')->nullable();
});
}
Is there any help i appreciated..
Sounds like Users migration file has been edited and needs re migrating. Run: php artisan migrate:refresh
Be warned This will remove anything stored within the database so ensure you have a Seeder setup to place any relevant content back into the database.
In the event you get an Laravel 5.4: Specified key was too long error on the re migrate open AppServiceProvider and add:
Schema::defaultStringLength(191); into the boot function
Ensure you add use Illuminate\Support\Facades\Schema; at the top of the AppServiceProvider file
For this issue SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table users add unique users_email_unique(email)) open your AppServiceProvider under App/Providers folder and add the below code:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Schema;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
Schema::defaultStringLength(191);
}
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
}
Try running below command to drop and migrate all the table again:
php artisan migrate:fresh
Note:
If your users table already migrated or exist and you wish to create a new table run below command :
php artisan make:migration contactus
then
php artisan migrate
When using the CLI make sure not to blindly copy other migration files.
first run php artisan make:migration create_contact_us_table
Now open the migration file location at /database/migrations/create_contact_us_table.php
Edit your migration here, inside the UP function you should then have something like
public function up()
{
Schema::create('contact_us', function(Blueprint $table){
$table->increments('id');
//Other table content
});
}
After this you can run php artisan migrate again to run your migration.
If you keep getting this error, check your database and the migrations table.
It might not have saved that it already ran your previous migration. If this is the case remove all tables from the database and run php artisan migrate again. Should work then.

Laravel 5.1 refresh and seed a single table

I'm looking to refresh and seed a single table in Laravel 5.1. Is this even possible?
I have tried the below, but it gives an error (incorrect syntax).
php artisan migrate:refresh --path=database/migrations/CreateTableTimesheet
If I use: php artisan migrate:refresh it just says:
Nothing to migrate
You could use migrate:refresh command that will roll back all of your migrations and then execute the migrate command. This command effectively re-creates your entire database :
php artisan migrate:refresh
And you may use the --class option to specify a specific seeder class to run individually :
php artisan db:seed --class=UserTableSeeder
The full code will be :
php artisan migrate:refresh
php artisan db:seed --class=UserTableSeeder
Hope this helps.
Its better to truncate your same table first and then seed:-
public function run()
{
Table::truncate();
//seed your table here
}
then you can run your same seeder like this:-
php artisan db:seed --class=YourSeeder
Maybe first just backup the database, drop it and check if whole seeding, migrating and refreshing mechanic works. But first dump artisan autoload.
I don't think any answer so far addresses the question of migrating and seeding a single table. So, given the migration file database/migrations/create_foo_table.php and the seed file database/seeds/FooTableSeeder.php, which contains the FooTableSeeder seed class, you can do the following:
php artisan migrate:refresh --path=database/migrations/create_foo_table.php
php artisan db:seed --class=FooTableSeeder
This will rollback, migrate and seed your Foo table. See: rolling back migrations and running seeders in the Laravel 5.1 documentation (at the time of writing this, Laravel 7.x is out and the syntax has not changed).
php artisan tinker
>>> App\Status::truncate()
Will clear the statuses table
So you can do
>>> App\{MODEL_CLASS}::truncate()
I found this quite useful when I don't want to clear all the tables, especially users.
include full table name
example
php artisan migrate:refresh --path='database/migrations/2014_10_12_000000_create_table_timesheet.php'
You can do it in two steps:
Refresh your specific table:
php artisan migrate:refresh --path=database/migrations/00_create_foo_table.php
Seed tables set in database/seeds/DatabaseSeeder.php:
composer dump-autoload
php artisan db:seed
=== Extra information ===
You can comment the seeders you don't want to use in DatabaseSeeder.php:
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* #return void
*/
public function run()
{
$this->call([
FooSeeder::class,
// BarSeeder::class,
// UserSeeder::class,
]);
}
}
In this example, only database/seeds/FooSeeder.php will be passed.

Resources