Wie man drei Tische nach einem eloquenten Laravel-Modell verbindet

80

Ich habe drei Tische

Artikeltabelle

 id
 title
 body
 categories_id
 user_id

Kategorietabelle

  id
  category_name

Benutzertabelle

 id
 user_name
 user_type

Ich möchte Artikel mit ihrem Kategorienamen anstelle von Kategorie-ID und Benutzername anstelle von Benutzer-ID anzeigen. Ich versuche wie diese Abfrage. Es ist Arbeit!

$articles =DB::table('articles')
                ->join('categories', 'articles.id', '=', 'categories.id')
                ->join('users', 'users.id', '=', 'articles.user_id')
                ->select('articles.id','articles.title','articles.body','users.username', 'category.name')
                ->get();

Aber ich möchte es auf eloquente Weise tun. Bitte, wie könnte ich tun?

Nein
quelle
1
Wie wäre es, wenn Sie eine Ansicht erstellen, die diese Tabellen verbindet, und dann ein eloquentes Modell erstellen, das nur daraus liest? Die Komplexität des Codes wird reduziert, Sie profitieren, es ist keine harte Arbeit erforderlich.
NB
1
Alle anderen verwandten Modelle und Funktionen arbeiten mit Eloquent Model zusammen. Also muss ich Eloquent Way verwenden.
Nein,
1
Irren Sie sich hier : ->join('categories', 'articles.id', '=', 'categories.id')? Stattdessen articles.idsollte es sein articles.categories_id. Oder liege ich falsch?
FreeLightman

Antworten:

133

Mit Eloquent ist es sehr einfach, relationale Daten abzurufen. Testen Sie das folgende Beispiel mit Ihrem Szenario in Laravel 5.

Wir haben drei Modelle:

1) Artikel (gehört zu Benutzer und Kategorie)

2) Kategorie (hat viele Artikel)

3) Benutzer (hat viele Artikel)


1) Article.php

<?php

namespace App\Models;
 use Eloquent;

class Article extends Eloquent{

    protected $table = 'articles';

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

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

}

2) Category.php

<?php

namespace App\Models;

use Eloquent;

class Category extends Eloquent
{
    protected $table = "categories";

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

}

3) User.php

<?php

namespace App\Models;
use Eloquent;

class User extends Eloquent
{
    protected $table = 'users';

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

}

Sie müssen Ihre Datenbankbeziehung verstehen und in Modellen einrichten. Benutzer hat viele Artikel. Kategorie hat viele Artikel. Artikel gehören zu Benutzer und Kategorie. Sobald Sie die Beziehungen in Laravel eingerichtet haben, können Sie die zugehörigen Informationen leicht abrufen.

Wenn Sie beispielsweise einen Artikel mithilfe des Benutzers und der Kategorie abrufen möchten, müssen Sie Folgendes schreiben:

$article = \App\Models\Article::with(['user','category'])->first();

und Sie können dies wie folgt verwenden:

//retrieve user name 
$article->user->user_name  

//retrieve category name 
$article->category->category_name

In einem anderen Fall müssen Sie möglicherweise alle Artikel innerhalb einer Kategorie oder alle Artikel eines bestimmten Benutzers abrufen. Sie können es so schreiben:

$categories = \App\Models\Category::with('articles')->get();

$users = \App\Models\Category::with('users')->get();

Weitere Informationen finden Sie unter http://laravel.com/docs/5.0/eloquent

Anand Patel
quelle
Vielen Dank für Ihre Antwort. Aber ich verwende Laravel 4 und möchte Daten im JSON-Format zurückgeben. return Response::json( array( 'total_count' => $count, 'incomplete_results' => false, 'items'=> $articles->toArray() ));Wie diese Wie kann ich das JSON-Format verwenden?
Nein,
Unabhängig davon, ob der gesamte Code in Laravel 4 funktioniert, müssen Sie nur den Namespace entfernen, und $ articles-> toArray () funktioniert genauso. Bitte versuchen Sie es
Anand Patel
Danke Bruder, es ist Arbeit und du rettest mein Leben :). Entschuldigung für die späte Antwort Da ich gestern nicht in der Nähe des Computers bin.
Nein,
4
Ich bin nicht sicher, aber es scheint, dass auf diese Weise (mit beredten) 3 Abfragen generiert. Während die Abfrage mit benutzerdefinierten joinist einfach. Die Antwort von @NayZawOo unten ist also akzeptabler.
FreeLightman
Was ist, wenn ich nicht wie $ article-> category-> category_name darauf zugreifen möchte, sondern einen Alias ​​wie $ article-> categoryName verwende? Wie schreibe ich in diesem Fall eine beredte Abfrage?
Herokiller
22

Versuchen:

$articles = DB::table('articles')
            ->select('articles.id as articles_id', ..... )
            ->join('categories', 'articles.categories_id', '=', 'categories.id')
            ->join('users', 'articles.user_id', '=', 'user.id')

            ->get();
Nein, Zaw Oo
quelle
Ich möchte, dass das JSON-Objektformat zurückgegeben wird. Weil ich $ articles-> count () und $ articles-> offset ($ offset) ausprobieren muss; $ articles-> get (array ('id', 'title', 'body')); Ihr Weg kann diese Objektfunktionen jedoch nicht anwenden. Vielen Dank für Ihre Unterstützung.
Nein,
1
Antwort: json ($ articles);
Nein Zaw Oo
Obwohl dies nicht die beredte Methode ist, ist dies die einzige Möglichkeit, wenn Sie nach Feldern in fremden Tabellen sortieren. (was ich nicht empfehlen würde, aber gelegentlich notwendig ist). Aus diesem Grund denke ich, dass dies immer noch eine sehr gültige Antwort ist. (die Frage gestellt , wie man beitreten Tabellen, die beredte Weise schließt sich eigentlich nie in der ursprünglichen Abfrage.)
Skeets
Dieses Paket kann Ihnen helfen github.com/fico7489/laravel-eloquent-join
fico7489
„Obwohl dies nicht die beredte Methode ist, ist es die einzige Möglichkeit, nach Feldern in fremden Tabellen zu sortieren.“ Skeets: Wenn Sie die einzige Methode sagen, sagen Sie, dass die Laravel-Dokumente diese wichtigen Informationen weglassen?
Glen
2
$articles =DB::table('articles')
                ->join('categories','articles.id', '=', 'categories.id')
                ->join('user', 'articles.user_id', '=', 'user.id')
                ->select('articles.id','articles.title','articles.body','user.user_name', 'categories.category_name')
                ->get();
return view('myarticlesview',['articles'=>$articles]);
Akshay Kashyap
quelle
Die obige Abfrage enthält einen Fehler bei der Verletzung der Integritätsbedingung, der in dieser Antwort behoben wurde
Akshay Kashyap,