Call to an undefined method Database\Factories\<MyModel>::trashed()
darfijt opened this issue · comments
- Larastan Version: 2.6.4
--level
used: 6
Description
I got warning about using the trashed
state method, that is defined in Illuminate\Database\Eloquent\Factories\Factory
Laravel code where the issue was found
$user = \App\Models\User::factory()->trashed()->create();
I even tried to annotate the method in my UserFactory
but this does not solve the issue. The only way I figurate out to solve the issue (without ignoring the line) is to define a custom state that calls parent trashed, but of course is not that cool
@darfijt, this works for me and the base factory class has the proper annotation:
Your user factory might need the proper generics:
/** @extends Factory<User> */
class UserFactory extends Factory
@ednar28, can you provide a minimum reproducible example? I am not seeing this error:
That's not an MRE...and the phpstan link I posted above is running on level 9
example my code:
/** DummyUserSeeder */
namespace Database\Seeders;
use App\Models\User;
use Illuminate\Database\Seeder;
class DummyUserSeeder extends Seeder {
/**
* Run the database seeds.
*/
public function run(): void
{
User::factory()
->count(10)
->trashed()
->create();
}
}
/** UserFactory */
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
*/
class UserFactory extends Factory
{
protected static ?string $password;
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'name' => fake()->name(),
'username' => fake()->unique()->userName(),
'email' => fake()->unique()->safeEmail(),
'email_verified_at' => now(),
'password' => static::$password ??= Hash::make('password'),
'remember_token' => Str::random(10),
];
}
}
Thanks, and the user model?
I thought it was a problem of my User model (since it extends another class) but I did the same on another model (that extends the lavarel base model) Factory and still the same issue.
So the following passes on Larastan 2.4.6 level 9:
<?php
namespace Tests\Larastan;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Seeder;
class User extends Model
{
use HasFactory;
use SoftDeletes;
protected $guarded = [];
protected $hidden = ['password'];
protected $table = 'users';
protected static function newFactory(): UserFactory
{
return UserFactory::new();
}
}
/** @extends Factory<User> */
class UserFactory extends Factory
{
protected $model = User::class;
/** @return array<string, mixed> */
public function definition(): array
{
return [
'name' => fake()->name(),
'email' => fake()->email(),
'password' => 'password', // set unencrypted
];
}
}
class UserSeeder extends Seeder
{
public function run(): void
{
User::factory()
->count(10)
->trashed()
->create();
}
}
I have the same issue as darfijt, but only in the context of my Pest tests. PHPStan picks up on the ->trashed()
method just fine in other contexts like seeders, etc.
I don't have time to make a full reproduction, but I can say that I'm on larastan 2.7.0, and more or less have the same key elements as your passing code, namely:
use HasFactory;
use SoftDeletes;
in the model and
/** @extends Factory<MyModel> */
in the factory.
I originally didn't have a definition for protected static function newFactory
set at first, but even when I added it, it didn't change the outcome inside Pest tests.