I'm trying to use a seeder to give, factory created, users the "membro" (member in Portuguese) role. So I have created the roles in a FuncoesSeeder (Funcoes = Functions, or roles in this context) like this:
Funcao::create(['nome' => 'Administrador', 'descricao' => 'Todas as permissões sobre utilizadores e funcionalidades.'])->save();
Funcao::create(['nome' => 'Gestor', 'descricao' => 'Acesso a todas as funcionalidades.'])->save();
Funcao::create(['nome' => 'Membro', 'descricao' => 'Acesso à página principal.'])->save();
Note: The primary key of Funcao is 'nome'.
Then I run UtilizadoresSeeder (Utilizadores = Users):
public function run()
{
$utilizador = Utilizador::create([
'nif' => 200000000, 'nome' => 'Name Surname', 'email' => 'name.surname@outlook.pt', 'telemovel' => 912345678,
'morada' => 'My address', 'codigo_postal' => '2100-123', 'localidade' => 'Ourém',
'data_admissao' => new DateTime('2000-10-09')
]);
$utilizador->funcoes()->attach('Administrador');
$utilizador->save();
$utilizadores = Utilizador::factory(20, new Sequence(fn ($sequence) => ['nif' => 100000000 + $sequence->index]))
->create(['password' => null]);
// Dictionary from Portuguese to English (even though the words are pretty similar)
// Descrição ("descricao" without special characters) - Description
// Funcao - Function (in this context is more like a role)
// funcoes - plural of funcao (functions/roles)
// Membro - Member
// Nome - Name
// utilizador(es) - user(s)
$funcao = Funcao::find('Membro'); //This works, and it should return a Funcao with ['nome' => 'Membro', 'descricao' => 'Acesso à página principal.']
echo ('NOME: ' . $funcao->nome . ' - DESCRIÇÃO: ' . $funcao->descricao . "\nJSON: " . $funcao->toJson());
$funcao->utilizadores()->attach($utilizadores);
}
I don't understand why, but the $funcao->nome returns 0 while $funcao->descricao is correct. I'm using a MySQL database and everything seems fine, plus the line "$utilizador->funcoes()->attach('Administrador');" works perfectly fine. I could probably do it with a foreach, like
foreach ($utilizadores as $utilizador) {
$utilizador->funcoes()->attach('Membro');
}
But I want to understand why this is happening, is it a database problem?
What am I doing wrong?
Definition of relationships and other stuff that I've double checked:
I've searched for spelling mistakes, but I haven't found any (I might be blind, but I don't think it's the case)
Funcoes table
Funcao model:
<?php
namespace App\Models\Utilizadores;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Funcao extends Model
{
use HasFactory;
protected $primaryKey = 'nome';
protected $table = 'funcoes';
public $timestamps = false;
protected $fillable = [
'nome',
'descricao'
];
public function utilizadores()
{
return $this->belongsToMany(Utilizador::class);
}
}
Since you are using a String type attribute as your primary key, you should state it so that Laravel act on that.
By default, for auto-incrementing tables, the ID is assumed to be an integer. By adding:
protected $keyType = 'string';
public $incrementing = false;
to your Funcao
Model, this problem should be resolved.