simon_eds's avatar

Unable to use one of my factories from tinker...

After upgrading to Laravel 8 from Laravel 5.8, I am unable to use just one of my factories in tinker using the following command:

Route::factory()->make();

This works no problem for my other factories, and I have checked everything looks correct.

This command returns the error: PHP Notice: Undefined offset: 0 in /vendor/laravel/framework/src/Illuminate/Routing/Router.php on line 1252 InvalidArgumentException with message 'Attribute [factory] does not exist.'

My route model -

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;



class Route extends Model
{
   use HasFactory;
    public function runs()
    {
        return $this->hasMany('App\Models\Run');
    } //



}


My factory -

namespace Database\Factories;

use App\Models\Route;
use Illuminate\Database\Eloquent\Factories\Factory;

class RouteFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = Route::class;

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        return [
            		'destination' => $this->faker->city,
			'miles' => rand(15,90),
			'name' => $this->faker->word,
			'type' =>$this->faker->randomElement($array = array('Blah', 'Blah1', 'Blah2', 'Blah3')),
			'owner' => $this->faker->name,
        ];
    }
}

Strangely (to me at least), I can use my db seeder and it works fine. This is using:

 $routes = Route::factory()->count(50)->create();

Any suggestions would be greatly appreciated!

0 likes
5 replies
Ishra's avatar

Tinker will try to guess which class you mean when you only write the classname and not the full namespace, in this case it is making a wrong guess.

Tinker thinks you are trying to use \Illuminate\Routing\Route, but you want to use \App\Models\Route

You might have to write the full namespace in tinker for this model, try this in tinker:

\App\Models\Route::factory()->make();
1 like
simon_eds's avatar

Thanks for the speedy reply @ishra. That does work as expected, thanks! Any idea as to why tinker is using this route for this model but not for any of my others? Any way to force tinker to use the correct route? It isn't that important, just annoying more than anything :-)

Ishra's avatar

The reason is probably because your other models does not have the same name as another class that already exists, but even if they have the same name i guess it's a bit of "luck" involved also, i don't know how exactly tinker works when guessing class to use.

I looked at the code and documentation for tinker and it appears to be a possibility to force Tinker to use your model.

https://laravel.com/docs/8.x/artisan#usage

publish the config and look at the 'alias' config option, i don't really know how it works or if it is the correct option for you. maybe not and you have to write the full namespace anyway in tinker.

Please mark the answer as accepted also if it helped you :)

Ishra's avatar
Ishra
Best Answer
Level 6

I thought about this some more, and i think the reason only Route have an issue is because Route is defined as an laravel alias i config/app.php

for example, I think you would get the same problem if you would create a model named Storage since that is also an alias defined in config/app.php.

That means you can also use config/app.php to fix your problem, either remove the alias defined there, it is probably only used in your route file anyway, so you would have to include a use statement for Illuminate\Support\Facades\Route at the top of your route files, laravel does not use the aliases internally anyway.

or...create a custom alias for your model that you can use in Tinker, example:

'R' => App\Models\Route::class,

and in tinker you can now write: R::factory()

I believe this would work, but i have not tested it.

Good luck! :)

simon_eds's avatar

Thanks for all your support. That is exactly the answer I was looking for! I guess I was just unlucky with naming my model the same as an aliased class. Thanks for providing a work around, but I guess it’s no big deal to just use the full namespace in tinker. It was more a matter of not understanding why it was behaving the way it was. Thanks again!

1 like

Please or to participate in this conversation.