Problema con seeders en Laravel

Publicado por Lynn
hace 5 meses

Hola a todos,

Estoy teniendo un problema al tratar de utilizar los seeders en Laravel para poblar mi base de datos. Tengo unas relaciones creadas en mis modelos y quiero que los datos se inserten correctamente en las tablas relacionadas. Sin embargo, cuando ejecuto el comando "php artisan db:seed", me aparece el siguiente error:

"Call to a member function relation() on null"

He revisado mi código y no veo ningún error obvio. ¿Alguien sabe a qué se debe este error y cómo puedo solucionarlo?

Aquí está mi código en el seeder:

use Illuminate\Database\Seeder;
use App\Producto;
use App\Categoria;

class ProductosSeeder extends Seeder
{
    public function run()
    {
        factory(Producto::class, 100)->create()->each(function ($producto) {
            $categoria = Categoria::inRandomOrder()->first();
            $producto->categoria()->associate($categoria);
        });
    }
}

Aquí está mi código en el modelo Producto:

use Illuminate\Database\Eloquent\Model;
use App\Categoria;

class Producto extends Model
{
    public function categoria()
    {
        return $this->belongsTo(Categoria::class);
    }
}

Y aquí está mi código en el modelo Categoria:

use Illuminate\Database\Eloquent\Model;
use App\Producto;

class Categoria extends Model
{
    public function productos()
    {
        return $this->hasMany(Producto::class);
    }
}

Agradezco cualquier ayuda que me puedan brindar. ¡Gracias de antemano!

seeders Laravel relaciones
Respuesta de Gordon Shumway
hace 5 meses

¡Hola Lynn!

El error "Call to a member function relation() on null" suele ocurrir cuando intentas llamar un método en un objeto que es null. Según el código que compartiste, el problema podría estar en esta línea del seeder:

$producto->categoria()->associate($categoria);

El error puede suceder si $categoria es null, ya que estarías intentando llamar al método associate en una relación a la que no se le ha podido asignar una instancia de Categoria.

Para solucionar este problema, asegúrate de que siempre haya al menos una Categoria en la base de datos antes de correr el seeder. También, es buena idea añadir una comprobación para asegurarse de que efectivamente se obtuvo una categoría:

use Illuminate\Database\Seeder;
use App\Producto;
use App\Categoria;

class ProductosSeeder extends Seeder
{
    public function run()
    {
        factory(Producto::class, 100)->create()->each(function ($producto) {
            $categoria = Categoria::inRandomOrder()->first();

            // Comprueba que realmente se encontró una categoría
            if ($categoria) {
                $producto->categoria()->associate($categoria);
                $producto->save(); // No olvides guardar el producto después de asociarlo
            }
        });
    }
}

Recuerda que $producto->save(); es necesario después de asociar la categoría para que la asociación se persista en la base de datos.

Por otro lado, si esto no resuelve tu problema, te sugeriría revisar tus factories y asegurarte de que las categorías se están creando antes que los productos. A veces, si el orden en el que se corren los seeders no es el correcto, podrías tratar de asociar productos a categorías que aún no existen.

¡Espero que esto te ayude a resolver el problema! Cualquier otra duda, aquí estamos.