Laravel 5.5 Model not found in Seed class - php

I have been around this problem for so long and cannot solve it... I found several people with (apparently) the same problem as me, but any of the answers helped me.
I have the following "Sector.php" inside "app" folder:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Sector extends Model
{
protected $table = 'sectors';
protected $fillable = ['name'];
protected $guarded = ['id'];
public function services()
{
return $this->belongsToMany('App\Service', 'services_sectors', 'sector_id', 'service_id');
}
public function observations()
{
return $this->belongsToMany('App\Observation', 'observations_sectors', 'sector_id', 'observation_id');
}
}
And the following "DatabaseSeeder.php" inside "database/seeds":
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
DB::table('sectors')->delete();
Sector::create(['name' => 'Health']);
$this->command->info('Sectors table seeded');
}
}
So, when I access my server I run the command php artisan db:seed but I have the following error:
[Symfony\Component\Debug\Exception\FatalThrowableError]
Class 'Sector' not found
I have been trying ./composer update, ./composer dump-autoload -o, changing Sector to App\Sector in the seeder file but the error just changes to Class 'App\Sector' not found.
If I add use App\Sector; to the top of the Seeder file the error is the same.
It seems I tried all the solutions that are online, so maybe I have some configuration done incorrectly? Any suggestions on this?

Try adding use App\Sector; to your seeding file.
Once you have it working, think about separating your seeding files into their separate classes. It is much easier to maintain that way.
Generate Seeder File
First, in terminal, generate a new seed file:
php artisan make:seeder SectorsTableSeeder
Transfer your seeding code into the run method of this new file.
Call seeder files
Then, modify the DatabaseSeeder.php file to run the SectorsTableSeeder class. For example:
public function run()
{
$this->call(SectorsTableSeeder::class);
}
Update
Sorry, I missed that part.
This is what I would try:
$now = date('Y-m-d H:i:s');
public function run()
{
DB::table('sectors')->delete();
DB::table('sectors')->insert([
'name' => 'Health',
'created_at' => $now,
'updated_at' => $now,
]);
$this->command->info('Sectors table seeded');
}

Related

Laravel Tasks - Storing when last ran

I've made CRON Job using Laravel's task scheduling. But what I need is to store somewhere when that task was last ran,
Does anyone have any methods of how they store that and also, If Laravel outputs anything that can tell you when it was last ran?
Thanks
Not possible directly, however it is possible if you cache a date-time string on each run (either at the beginning or end of your script).
Cache::rememberForever('name_of_artisan_task', function () {
return now()->toDateTimeString();
});
The example shows using the Cache facade's ::rememberForever method to create a key/value of the last time the task was ran. As the name suggests, this is saved forever.
You can easily retrieve this date and time using the cache() helper:
cache('name_of_artisan_task');
The con with this method is that if your cache is cleared, you will not longer have this stored.
Using a cache is not a safe way to do this, as #thisiskelvin hinted, clearing the cache will remove the data (which should happen on each deployment) but he didn't provide an alternative
So here is one if you need this date reliably (if you use it to know the interval to run an export for instance)
In which case I recommend creating a model php artisan make:model ScheduleRuns -m
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
/**
* #property string $task
*/
class ScheduleRuns extends Model
{
public const UPDATED_AT = false;
public $timestamps = true;
protected $attributes = [
'task' => '',
];
protected $fillable = [
'task',
'created_at',
];
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('schedule_runs', function (Blueprint $table) {
$table->id();
$table->string('task');
$table->timestamp('created_at')->nullable();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('schedule_runs');
}
};
Then use schedule hooks to create it (or do it within the task if you want to avoid possible seconds differences)
$schedule->command('export:users')
->weekly()->onSuccess(fn () => ScheduleRuns::create(['task' => 'export:users']))
And to retrieve the latest run
ScheduleRuns::query()->where('task', 'export:users')->latest();
Just write log each time the task was run, or you can push it into database.
<?php
namespace App\Console\Commands\Tasks;
use Illuminate\Console\Command;
class ScheduledTask extends Command
{
public function handle()
{
//
// ...handle you task
//
$file = 'logs/jobs/' . __CLASS__ . '.log';
$message = 'Executed at: ' . date('Y-m-d H:i:s', time());
file_put_contents(storage_path($file), $message, FILE_APPEND);
}
}

laravel observers are not working

I am trying to listen to model events using laravel observers .The problem is when i submit my form (update or creating new records), nothing happened at all .Do i miss something ?
app.php
'providers' => [
...
App\Providers\CasesManagerServiceProvider::class,
]
CasesManagerServiceProvider.php
class CasesManagerServiceProvider extends ServiceProvider
{
public function boot( )
{
Cases::observe(CasesObserver::class);
}
public function register()
{
}
}
CasesObserver.php
class CasesObserver
{
private $cases;
public function __construct(Cases $cases){
$this->cases = $cases;
}
public function creating(Cases $case)
{
dd('creating');
}
public function saved(Cases $case)
{
dd('saved');
}
public function updating($case)
{
dd('updating');
}
public function updated($case)
{
dd('updated');
}
}
Cases.php
class Cases extends Model
{
const UPDATED_AT = 'modified_at';
protected $dispatchesEvents = [
'updating' => CasesObserver::class,
'updated' => CasesObserver::class,
'creating' => CasesObserver::class,
'saved' => CasesObserver::class,
];
}
for me, the problem was registering observer in the register() method!
so when I put it in the boot() method every thing worked well! the reason is the order of running methods in service providers which are mentioned hear
hope be useful
Ok i have found my answer . All the problem was when I added
use app\Observers\CasesObserver; in CasesManagerServiceProvider.php instead of use App\Observers\CasesObserver; .
Yes the Camel case of App was the problem, so i changed to App and all things are working fine now.
It seems to be a misuse of Composer and Laravel themselves.
You should inform them that you have added some files and configurations:
To autoload the files:
composer dump
To reconfigure the cache:
php artisan config:cache
Hope this help you too!
You do not need to use $dispatchesEvents in your case. You should try to remove $dispatchesEvents from model, and remove __constructor() from CasesObserver.
The reason is that you have to add a HasEvents trait to your model
<?php
use Illuminate\Database\Eloquent\Concerns\HasEvents;
class MyModel extends Model
{
use HasEvents;
//your code goes here
}
Not possible according to the documentation. When issuing a mass update or delete query via Eloquent.

Laravel Seeding missing classes

I am following this tutorial until I need to generate seeds using: php artisan db:seed. It always said that my Article and User class are not found.
I have looking for solution like in:
https://laracasts.com/discuss/channels/lumen/unable-to-run-php-artisan-dbseed-due-to-missing-class (setting up composer.json's auto load paths and composer dump-autoload)
Laravel cannot find class of a package
I have deleting my vendor folder and do composer install again
Also importing the file manually, require_once with relative path to the model from the seeding or root of the projet, but neither works.
I think this should work out-of-the-box but it isn't. What is my problem? And what is my solution?
EDIT 1: Someone requested seeders codes here you are!
Article Seeder
<?php
use Illuminate\Database\Seeder;
class ArticlesTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
// Let's truncate our existing records to start from scratch.
Article::truncate();
$faker = \Faker\Factory::create();
// And now, let us create a few articles in our database:
for ($i = 0; $i < 50; $i ++) {
Article::create([
'title' => $faker->sentence,
'body' => $faker->paragraph,
]);
}
}
}
User Seeder
<?php
use Illuminate\Database\Seeder;
class UsersTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
// Let's clear the user table first
User::truncate();
$faker = \Faker\Factory::create();
// Let's make sure everyone has the same password and
// let's hash it before the loop, or else our seeder
// will be too slow.
$password = Hash::make('toptal');
User::create([
'name' => 'Administrator',
'email' => 'admin#test.com',
'password' => $password,
]);
// And now let's generate a few dozen users for our app:
for ($i = 0; $i < 10; $i ++) {
User:;create([
'name' => $faker->name,
'email' => $faker->email,
'password' => $password,
]);
}
}
}
Database Seeder
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
$this->call(UsersTableSeeder::class);
$this->call(ArticlesTableSeeder::class);
}
}
First you should import the full class path, i.e.- App\User. Then regenerate the autoload file with- composer dump-autoload
You should either import the models that you've use so you can use just the Model's class name in your code or use the fully qualified name of the Model.
E.g., instead of just User, use App\User.
Use imports if you think you will have many instance where you will use the User class name, to avoid the hassle of typing the fully qualified name.
<?php
...
use App\User;
...
$users = User::all(); // <-- now you can do this.
I followed the same tutorial. Just add a line "use App\Article;" so that your class will find the appropriate class.
Its like including a header file path in c/c++.

Laravel 5.3 ModelFactory Seeder Call to undefined method Illuminate\Database\Query\Builder::posts()

Im trying to create a seeder table that fills a table with some dummy data using the laravel ModelFactory. I keep getting this error and I'm out of ideas on fixing it.
The 'Race' Model
<?php
namespace App\Game;
use Illuminate\Database\Eloquent\Model;
class Race extends Model
{
//
public $timestamps = false;
protected $fillable = ['name','description','icon'];
}
File 2 The Model Factory File
$factory->define(App\Game\Race::class, function (Faker\Generator $faker) {
return [
'name' => $faker->name,
'description' => $faker->text,
'icon' => $faker->url,
];
});
File 3 The Seeder File
<?php
use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;
class RacesTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
//
factory(App\Game\Race::class, 10)->create()->each(function($u) {
$u->posts()->save(factory(App\Game\Race::class)->make());
});
}
}
I am getting the following error
Call to undefined method Illuminate\Database\Query\Builder::posts()
This happens when I call 'php artisan db:seed'
It looks like you copied the seeder directly from the documentation. In the documentation's example, there is a User model that is related to a Posts model via a function posts that is defined within the user model. See this documentation page for more information about why there's a posts method on the User model.
You have a Race model that does not have Posts related to it, indicated by the absence of posts method inside your race model. Try simplifying the factory to this:
public function run()
{
//
factory(App\Game\Race::class, 10)->create();
}
This should create 10 race entries in your database for you. You would want to provide the closure passed to the each method only if you intend to also create other models within the seeder that are related to each instance the factory creates, or do some other action for every instance (each) of a Race that gets created by the factory.

Laravel Call to undefined method create() and save()

I'm trying to seed my DB but I have a problem when I use modelName::create() or $modelName->save().
I have this kind of error
{"error":{"type":"Symfony\Component\Debug\Exception\FatalErrorException","message":"Call to undefined method Doc::save()","file":"/Applications/MAMP/htdocs/Doc_project/app/database/seeds/DatabaseSeeder.php","line":45}
or
Call to undefined method Doc::create()
but i dont know why.
My Model :
class Doc extends Eloquent {
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'doc';
protected $fillable = array('creators_name', 'type_document', 'title', 'description');
public function steps(){
return this->hasMany('Step')
}
public function tags(){
return this->belongsToMany('Tag', 'doc_tag', 'id_doc', 'id_tag')
}
}
My Seeder :
class DatabaseSeeder extends Seeder {
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
Eloquent::unguard();
$this->call('DocAppSeeder');
$this->command->info('Doc app seeds finished.'); // show information in the command lin }
}
}
class DocAppSeeder extends Seeder {
public function run(){
DB::table('doc')->delete();
DB::table('step')->delete();
DB::table('tag')->delete();
DB::table('doc_tag')->delete();
/* DB::table('doc')->insert(array(
'creators_name' => 'Alexis',
'type_document' => 'Solution',
'title' => 'NoAD Printer',
'description' => 'Installation imprimante en NoAd'
));*/
$doc = new Doc;
$doc->creators_name = 'Alexis';
$doc->type_document = 'Solution';
$doc->title = 'NoAD Printer';
$doc->description = 'Installation imprimante en NoAd';
$doc->save();
/*$docTest = Doc::create(array(
'creators_name' => 'Alexis',
'type_document' => 'Solution',
'title' => 'NoAD Printer',
'description' => 'Installation imprimante en NoAd'
));
}
}
I try with DB::Table(...)->insert(...)it works, but I can't use it because I need to get some information on each object
Someone have an idea?
Thank you
It looks like PHP is using a different global level Doc class than the one you think it is. Maybe for a facade or alias (self link, contains details instructions on how to debug facade issues)?
Regardless, the best course of action is to see where PHP thinks this class is. In you seeder, right before save, include the following debugging code
$r = new ReflectionClass('Doc');
var_dump(
$r->getFilename()
); 
var_dump(
$r->getName()
);
This will tell you the full-name of the class (if it's an alias) and where the class is defined. My guess is the class you think is Doc is not your Eloquent model, and is, in fact, a different class.
Based on your comments below, it sounds like someone's defined a class named Doc in
/Applications/MAMP/htdocs/Doc_project/app/database/migrations/2014_10_12_201016‌​_doc.php
This isn't normal -- although it's easy to see how it might have happened. You probably used the artisan command to create a migration like this
php artisan migrate:make doc
By not using the more explicate form
php artisan migrate:make create_doc_table
You inadvertently create a migration class with the same name as your model. Try recreating this migration with a less specific name, and you should be all set.
Check your migration file -
Rollback the migration, create a fresh version of migration file and proceed.
It usually happens with artisans when used to create a migration.
For me, i rollback the migration and recrested the migration with another name and it works.

Categories