J'ai 2 tables, users et websites. Un utilisateur peut se voir attribuer plusieurs sites Web.

public function websites() {
    return $this->hasMany('App\Models\Website');
}

L'erreur que j'obtiens est:

Object of class Illuminate\Database\Eloquent\Relations\HasMany could not be converted to string

Si j'essaie de le sortir comme un tableau en utilisant print_r, j'obtiens des centaines de lignes de tableau qui, je suppose, sont causées par une erreur quelque part.

Aussi, pourquoi dois-je utiliser App\Models\Website dans la méthode hasMany si j'ai spécifié en haut de User model use App\Models\Website;?

Si j'utilise uniquement Website dans la méthode, j'obtiens une erreur de classe introuvable:

Class 'Website' not found

Ce n'est pas grave, mais il serait beaucoup plus propre de ne pas avoir à utiliser le chemin complet de l'espace de noms.

Le code dans le contrôleur:

<?php namespace App\Http\Controllers;

use DB;
use App\User;

class DashboardController extends Controller {

    /*------------------------------------------------------------------
        Dashboard page
    -------------------------------------------------------------------*/
    public function show() {

        //$user = auth()->user();
        $user = User::find(5);

        return $user->websites();

        //return view('dashboard');
    }

};
8
zen 3 janv. 2016 à 02:53

2 réponses

Meilleure réponse

La fonction websites() elle-même n'est pas à l'origine de l'erreur. L'erreur vient de l'endroit où vous utilisez la fonction.

La fonction hasMany() renvoie un objet Illuminate\Database\Eloquent\Relations\HasMany. Ainsi, lorsque vous appelez $user->websites(), cela renverra l'objet de relation HasMany. Partout où vous utilisez cette fonction, vous essayez alors de convertir ce résultat en une chaîne, qui est l'erreur que vous voyez.

Par exemple:

$user = User::find(1);
echo $user->websites();

Dans cet exemple, si vous essayez de echo la réponse de la méthode websites(), vous obtiendrez l'erreur "n'a pas pu être converti en chaîne".

Si cela ne vous aide pas suffisamment pour résoudre le problème, vous devrez publier le code qui appelle la fonction websites() pour que quiconque puisse vous aider davantage.

Éditer

"Le contrôleur ne fait pas écho à la méthode des sites Web (), il la renvoie simplement." Tout ce qui est retourné par une méthode de contrôleur est converti en chaîne. Ceci est votre problème.

Au lieu de renvoyer l'objet HasMany, vous devez renvoyer les résultats de l'objet HasMany. Il y a deux options principales: appeler get() sur la relation pour obtenir réellement les résultats et renvoyer cela, ou utiliser l'attribut de relation au lieu de la méthode.

Option 1:

public function show() {
    $user = User::find(5);

    // call "get()" to get the results
    return $user->websites()->get();
}

Option 2:

public function show() {
    $user = User::find(5);

    // use lazy loaded attribute instead of using relationship method
    return $user->websites;
}

Les deux options ci-dessus renverront la même chose: un Collection des objets Website. Puisque vous renvoyez ceci du contrôleur, Laravel le convertira en chaîne, ainsi votre sortie sera un tableau json d'objets json Website.

21
patricus 3 janv. 2016 à 18:05

J'ai quelques solutions possibles:

Tout d'abord, avez-vous défini la relation inverse?

User.php

public function websites() {
    return $this->hasMany('App\Models\Website');
}

Site Web.php

public function user()
{
    return $this->belongsTo('App\Models\User');
}

Deuxièmement, avez-vous exécuté composer dump-autoload dans le terminal.

Notez que si vous voulez une interface plus propre, vous pouvez cela si vous utilisez> = php 5.5

User.php

public function websites() {
    return $this->hasMany(App\Models\Website::class);
}

Ou

use App\Models\Website;

public function user() {
    return $this->hasMany(Website::class);
}

Modifier 1

Vos modèles ont-ils le bon espace de noms?

namespace App\Models;

Modifier 2

Vous pouvez essayer 2 autres choses.

<?php namespace App\Http\Controllers;

use DB;
use App\User;

class DashboardController extends Controller {

    public function show() {
        $user = User::find(5);
        return $user->websites()->toArray();
    }

    // this one will query the database only once.

    public function newShow() {
        $user = User::with('websites')->find(5);
        return $user->websites->toArray();
    }

};
3
whoacowboy 3 janv. 2016 à 18:07