J'ai un modèle Task. Mon modèle Task a des relations et il ressemble actuellement à ceci:

class Task extends Model
{
    use HasFactory;

    public $timestamps = false;

    public function city()
    {
        return $this->hasOne(City::class, 'id', 'city_id');
    }

    public function type()
    {
        return $this->hasOne(Type::class, 'id', 'type_id');
    }

    public function note()
    {
        return $this->hasOne(Note::class, 'id', 'note_id');
    }

    public function operator()
    {
        return $this->hasOne(User::class, 'id', 'operator_id');
    }
}

Maintenant, dans mon TasksController, j'ai besoin d'obtenir des tâches qui correspondent à certains critères, comme ceci:

$tasks = Task::whereCityId($city->id)->whereTypeId($type->id)->get()->toArray();

Le problème est que les champs nommés city_id type_id note_id operator_id obtiendront mes integer valeurs qu'ils ont.

Au lieu de cela, je voudrais obtenir une certaine valeur d'un modèle connexe.

Par exemple:

operator_id doit être remplacé par username de la table User qui correspond à l'ID utilisateur.

Une solution évidente à cela serait d'utiliser simplement la boucle foreach, de parcourir mes résultats et d'obtenir les données dont j'ai besoin et de créer simplement un autre tableau avec les informations remplacées, mais je ne suis pas sûr que ce soit la meilleure idée et peut-être il y a quelque chose de mieux.

1
AlphaOmega 1 mars 2021 à 13:29

3 réponses

Meilleure réponse

Vous devez changer votre code:

$this->hasOne(ClassName::class, 'id', 'foreign_key');

À

$this->belongsTo(ClassName::class, 'foreign_key', 'id');

Car l'ID de la tâche n'est pas disponible en tant que clé étrangère dans ces tables. L'identifiant de cette table est présent dans la table des tâches en tant que clé étrangère, vous devez donc utiliser la relation appartient à () pour indiquer au script d'où appartient cet identifiant.

Ensuite, accédez à des propriétés comme celle-ci:

$tasks = Task::with("type", "city", "operator")
->whereCityId($city->id)->whereTypeId($type->id)->get();

foreach($tasks as $task){
   echo $task->city->name;
}
0
Surender Singh Rawat 1 mars 2021 à 11:15

Vous devez d'abord réparer votre relation:

public function city()
    {
        return $this->hasOne(City::class,'city_id','id'); 
    }

Et donc une même erreur, la clé étrangère dans l'ordre des arguments vient avant la clé primaire.

Après cela, vous pouvez utiliser addSelect:

 $tasks = Task::whereCityId($city->id)->whereTypeId($type->id)
            ->addSelect(['userName' => User::select('name')
                ->whereColumn('users.id', 'tasks.operator_id')
                ->limit(1)])->get()->toArray();
0
OMR 1 mars 2021 à 10:44

Je pense que cela aidera mieux que ce que vous demandez.

$tasks = Task::whereCityId($city->id)
->whereTypeId($type->id)
->with('operator')
->get()->toArray();

with('operator') est une fonctionnalité ORM qui permet à votre collection d'inclure sa relation en tant que propriété de collection. Dans ce cas, il sera converti en propriété de tableau.

Vous pouvez y accéder depuis votre fonction foreach en tant que

@foreach($task as $key)
$key['operator']['username']
@endforeach

Bonne journée

0
Muhamad Rafi Pamungkas 1 mars 2021 à 10:49