Laravel hasMany-Methode funktioniert nicht
Ich habe 2 Tabellen, users
und websites
. Ein Benutzer kann mehreren websites zugeordnet werden.
public function websites() {
return $this->hasMany('App\Models\Website');
}
Den Fehler den ich bekomme, ist:
Object of class Illuminate\Database\Eloquent\Relations\HasMany could not be converted to string
Wenn ich versuche, Ausgabe, die es als ein array mit print_r
bekomme ich Hunderte von Zeilen-array, die ich gehe davon ist, verursacht durch einen Fehler irgendwo.
Auch, warum ich App\Models\Website
im hasMany
Methode, wenn ich angegeben, an der Spitze der User
Modell use App\Models\Website;
?
Wenn ich nur Website
in der Methode, bekomme ich die Klasse nicht gefunden Fehler:
Class 'Website' not found
Nicht eine große Sache, aber es wäre viel sauberer, nicht zu haben, um den vollen namespace-Pfad.
Den code in den controller:
<?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');
}
};
- Wenn Sie nicht wollen, um die Referenz der vollständige namespace in der Beziehung, die Sie verwenden können, die PHP 5.5
::class
statischen Verweis.return $this->hasMany(Website::class);
. Für deine eigentliche Frage, wie sind Sie zu benutzen versuchen, die Beziehung? Was wollen Sie erreichen?$user->websites
werden Sie wieder eine Collection/Array der Ergebnisse in der Erwägung, dass$user->websites()
werden Sie wieder eine query-Instanz zur Abfrage der Webseiten, die dem Benutzer gehören. - Ich versuche nur, um alle websites, die der Benutzer hat. Ich kann ihn einfach wie dieses
$websites = Website::where('user_id', '=', $user->id)->get();
aber ich wollte die Methode gereinigt, wenn Sie und auch herausfinden, warum dieser Methode ist nicht für mich arbeiten. - Haben Sie gezielt setzen Sie Ihre Modelle in
App\Models`? By default they are just inside
App` und so würden Sie darauf verweisen, wieApp\Website
. - Auch, ich nehme es, dass Ihre website Tabelle verweist auf den Benutzer, der Sie besitzt, in eine Spalte namens
user_id
gegeben, die Sie noch nicht angegeben, eine andere Spalte? - Ja habe ich alle meine Modelle von innen
App\Models
. Nur eine in derApp
Benutzer, die die Standard-Modell. Ich kann bewegen, die zu derApp\Models
später auch. - Ja, das ist auch korrekt. Es ist ein
user_id
Spalte in derwebsites
Tabelle. Wie ich bereits in dem anderen Kommentar kann ich problemlos abrufen, dass Informationen mithilfe von query builder. Ich versuche nur, um zu sehen, warum es funktioniert nicht auf diese andere Art und Weise
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den
websites()
Funktion selbst ist nicht die Ursache der Fehler. Der Fehler kommt von dort, wo Sie die Funktion.Den
hasMany()
- Funktion gibt einenIlluminate\Database\Eloquent\Relations\HasMany
Objekt. Also, wenn Sie anrufen$user->websites()
diese zurückHasMany
Beziehung Objekt. Wo auch immer Sie sind, mit dieser Funktion, Sie werden dann versuchen, zu konvertieren das Ergebnis in eine Zeichenfolge, die die Fehlermeldung, die Sie sehen.Beispiel:
In diesem Beispiel, wenn Sie versuchen, um
echo
die Antwort von derwebsites()
- Methode, erhalten Sie die "konnte nicht in eine Zeichenfolge konvertiert werden" - Fehler.Wenn das nicht hilft, Sie genug, um das Problem zu beheben, müssen Sie nach dem code, der den Aufruf der
websites()
Funktion für jedermann in der Lage sein weiter zu helfen.Bearbeiten
"Der controller nicht die echo-websites () - Methode, die es gerade gibt es zurück." Alles kehrte von einer controller-Methode in einen string umgewandelt. Das ist Ihr Problem.
Anstatt die
HasMany
Objekt, müssen Sie die Ergebnisse derHasMany
Objekt. Es gibt zwei Optionen: callget()
auf die Beziehung tatsächlich bekommen die Ergebnisse-und zurück, oder verwenden Sie die Beziehung Attribut anstelle der Methode.Option 1:
Option 2:
Beide der oben genannten Optionen wird das gleiche zurückgeben: ein
Collection
desWebsite
Objekte. Da bist du wieder in dieser von der Steuerung, Laravel konvertieren diese in einen string, so dass Ihr Ergebnis wird ein json-array mit json -Website
Objekte.User::find(5)
bekomme ich den gleichen Fehler. Wenn ich versuche, print_r das Ergebnis, es buchstäblich Ausgänge Hunderte, wenn nicht Tausende von Zeilen-lange-array das sieht eher aus wie laravel-system-Kram als alles andere in der Datenbank.Habe ich ein paar mögliche Lösungen:
Ersten, haben Sie die inverse Beziehung definiert?
User.php
Website.php
Zweitens haben Sie ausgeführt
composer dump-autoload
im terminal.Hinweis: wenn Sie möchten, eine sauberere Schnittstelle können Sie diese, wenn Sie mit >= php 5.5
User.php
oder
Bearbeiten 1
Tun Sie Ihre Modelle haben den richtigen namespace?
Edit 2
Könnten Sie versuchen, 2 weitere Dinge.
user
Methode sollte in Website.php undwebsites
Methode in User.php. Den Fehler immer noch gibt, wieObject of class Illuminate\Database\Eloquent\Relations\HasMany could not be converted to string
HasMany
) nicht implementieren dietoArray()
Methode. Dein zweites Beispiel würde funktionieren, aber ist ein wenig überflüssig, datoArray
wird aufgerufen auf die Sammlung, wenn es in einen string konvertiert.toArray()
ist nicht auf die Beziehung, aber es ist der run auf die Kollektion, die von der Abfrage zurückgegeben wird. 2. DieUser::with('websites')->find(5);
verwendet eine sich so nur eine Abfrage gegen die Datenbank laufen.toArray()
auf die Beziehung Methode, nicht die Beziehung-Attribut. (d.h.websites()->toArray()
, nichtwebsites->toArray
). Das heißt, Sie sind geforderttoArray()
auf dieHasMany
- Objekt-Beziehung, die Ihnen einen "Call to undefined method Illuminate\Database\Query\Builder::toArray ()" - Fehler. Mit der Methode anstelle des Attributs kann ein Schreibfehler in deiner Antwort, aber es ist ein großer Unterschied.select * from users where users.id = 5 limit 1
, und die zweite Abfrage wirdselect * from websites where websites.user_id in (5)
. Wenn Sie eine chance bekommen, aktivieren Sie die Abfrage-Protokoll auf einem tinker-Sitzung und überprüfen Sie die Abfragen ausführen, wenn dabei die Beziehung Zeug. Außerdem können Sie durch den code gehen, um zu überprüfen, wie gut.User::with('websites')->get()
die erste Abfrage wäreselect * from users
, und die zweite wäreselect * from websites where websites.user_id in (?, ?, ?, ? ?)
. Dies lädt alle Webseiten für alle Benutzer in einer Abfrage. Wenn Sie nur auf Sie berufen, lazy loading, wäre es das website-Abfrage für jeden Benutzer einmal Objekt, das Sie zugreifen (daher N+1).