Jak dołączyć do trzech stolików według elokwentnego modelu Laravel


85

Mam trzy stoliki

Tabela artykułów

 id
 title
 body
 categories_id
 user_id

Tabela kategorii

  id
  category_name

Tabela użytkowników

 id
 user_name
 user_type

Chcę wyświetlać artykuły z nazwą kategorii zamiast category_id i user_name zamiast user_id. Próbuję odpowiedzieć na to zapytanie. To działa!

$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();

Ale chcę to zrobić elokwentnie. Proszę, jak mogłem zrobić?


1
Co powiesz na utworzenie widoku łączącego te tabele, a następnie utworzenie modelu Eloquent, który po prostu z niego odczytuje? Zmniejszona złożoność kodu, zysk, bez ciężkiej pracy.
Uwaga:

1
Wszystkie inne powiązane modele i funkcje działają razem z Eloquent Model. Więc muszę użyć Eloquent Way.
Nie

1
Czy pomylić tutaj: ->join('categories', 'articles.id', '=', 'categories.id')? Zamiast articles.idtego powinno być articles.categories_id. A może się mylę?
FreeLightman

Odpowiedzi:


140

Dzięki Eloquent bardzo łatwo jest odzyskać dane relacyjne. Sprawdź następujący przykład ze swoim scenariuszem w Laravel 5.

Mamy trzy modele:

1) Artykuł (należy do użytkownika i kategorii)

2) Kategoria (zawiera wiele artykułów)

3) Użytkownik (zawiera wiele artykułów)


1) Artykuł.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');
    }

}

Musisz zrozumieć relacje z bazą danych i konfigurację modeli. Użytkownik ma wiele artykułów. Kategoria zawiera wiele artykułów. Artykuły należą do użytkownika i kategorii. Po skonfigurowaniu relacji w Laravel łatwo będzie odzyskać powiązane informacje.

Na przykład, jeśli chcesz pobrać artykuł za pomocą użytkownika i kategorii, musisz napisać:

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

i możesz użyć tego w ten sposób:

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

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

W innym przypadku może zajść potrzeba pobrania wszystkich artykułów w kategorii lub wszystkich artykułów określonego użytkownika. Możesz to napisać tak:

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

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

Możesz dowiedzieć się więcej na http://laravel.com/docs/5.0/eloquent


Dzięki za odpowiedź Ale używam laravel 4 i chcę zwracać dane w formacie json. Podobnie jak te return Response::json( array( 'total_count' => $count, 'incomplete_results' => false, 'items'=> $articles->toArray() ));Jak mogę zrobić dla formatu json?
Nie

Bez względu na wszelkie prace kodu w laravel 4 prostu trzeba usunąć nazw i $ ArtykuĹ,y> toArray () działa tak samo, spróbuj
Anand Patel

Dzięki tobie bracie to praca i ratujesz mi życie :). Przepraszam za spóźnioną odpowiedź, ponieważ wczoraj nie było mnie w pobliżu komputera.
Nay

4
Nie jestem pewien, ale wydaje się, że w ten sposób (elokwentnie) generuje 3 zapytania. Podczas gdy zapytanie z niestandardowymi joinbędzie pojedyncze. Więc odpowiedź @NayZawOo poniżej jest bardziej akceptowalna.
FreeLightman

co jeśli nie chcę uzyskać do niego dostępu, takiego jak $ article-> category-> category_name, ale używam aliasu, takiego jak $ article-> categoryName, jak w takim przypadku napisać wymowne zapytanie?
Herokiller,

23

Próbować:

$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();

Chcę, aby powrócił format obiektu JSON. Ponieważ muszę wypróbować $ artykuly-> count () i $ artykuly-> offset ($ offset); $ artykuły-> get (tablica ('id', 'tytuł', 'treść')); Ale Twój sposób nie może zastosować tych funkcji obiektów. Dziękuję za wsparcie.
Nay

1
odpowiedź zwrotna: json ($ artykuły);
Nie Zaw Oo

Chociaż nie jest to wymowny sposób, aby to zrobić, jest to jedyny sposób, jeśli sortujesz według pól w obcych tabelach. (czego nie polecam, ale czasami jest to konieczne). Z tego powodu uważam, że jest to nadal bardzo ważna odpowiedź. (pytanie zadane, jak dołączyć do stołów, wymowny sposób w rzeczywistości nigdy nie łączy ich w pierwotnym zapytaniu.)
Skeets


„Chociaż nie jest to wymowny sposób, aby to zrobić, jest to jedyny sposób, jeśli sortujesz według pól w obcych tabelach.” Skeets, kiedy mówisz jedyny sposób, czy twierdzisz, że laravel docs pomijają tę ważną informację?
Glen

3
$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]);

Powyższe zapytanie zawiera błąd naruszenia ograniczenia integralności, który został rozwiązany w tej odpowiedzi
Akshay Kashyap,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.