Как присоединиться к трем столам от laravel eloquent model


85

У меня три стола

Таблица статей

 id
 title
 body
 categories_id
 user_id

Таблица категорий

  id
  category_name

Таблица пользователей

 id
 user_name
 user_type

Я хочу показывать статьи с их названием категории вместо category_id и user_name вместо user_id. Я пытаюсь сделать этот запрос. Это работает!

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

Но я хочу поступить красноречиво. Пожалуйста, как мне это сделать?


1
Как насчет создания представления, которое объединяет эти таблицы, а затем вы создаете модель Eloquent, которая просто читает из нее? Снижение сложности кода, вы получаете прибыль, без тяжелой работы.
NB,

1
Все остальные связанные модели и функции работают вместе с Eloquent Model. Поэтому мне нужно использовать Eloquent Way.
Нет,

1
Вы ошиблись здесь: ->join('categories', 'articles.id', '=', 'categories.id')? Вместо articles.idэтого должно быть articles.categories_id. Или я не прав?
FreeLightman

Ответы:


140

С Eloquent очень легко получать реляционные данные. Ознакомьтесь со следующим примером с вашим сценарием в Laravel 5.

У нас есть три модели:

1) Статья (относится к пользователю и категории)

2) Категория (много статей)

3) Пользователь (имеет много статей)


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');
    }

}

Вам необходимо понять отношения и настройки вашей базы данных в моделях. У пользователя много статей. В категории много статей. Статьи относятся к пользователю и категории. После того, как вы настроите отношения в Laravel, становится легко получить связанную информацию.

Например, если вы хотите получить статью, используя пользователя и категорию, вам нужно будет написать:

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

и вы можете использовать это так:

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

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

В другом случае вам может потребоваться получить все статьи в категории или получить все статьи определенного пользователя. Вы можете написать это так:

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

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

Вы можете узнать больше на http://laravel.com/docs/5.0/eloquent


Спасибо за ответ. Но я использую laravel 4 и хочу, чтобы данные возвращались в формате json. return Response::json( array( 'total_count' => $count, 'incomplete_results' => false, 'items'=> $articles->toArray() ));Как это сделать для формата json?
Нет,

Независимо от того, что весь код работает в Laravel 4, вам просто нужно удалить пространство имен, а $ article-> toArray () работает так же, попробуйте
Ананд Патель

Спасибо тебе, брат, это работа, и Ты спас мне жизнь :). Извините за поздний ответ, потому что вчера меня не было рядом с компьютером.
Нет,

4
Я не уверен, но похоже, что этот способ (с использованием красноречивого) генерирует 3 запроса. Хотя запрос с custom joinбудет одиночным. Так что ответ @NayZawOo ниже более приемлем.
FreeLightman

что, если я не хочу получать к нему доступ, например, $ article-> category-> category_name, но использую какой-нибудь псевдоним, например $ article-> categoryName, как мне написать красноречивый запрос в этом случае?
Herokiller

23

Пытаться:

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

Я хочу вернуть формат объекта json. Потому что мне нужно попробовать $ article-> count () и $ article-> offset ($ offset); $ article-> get (array ('идентификатор', 'заголовок', 'тело')); Но Ваш способ не может применять эти объектные функции. Спасибо за вашу поддержку.
Нет,

1
Ответ возврата: json ($ article);
Nay Zaw Oo

Хотя это не очень красноречивый способ сделать это, это единственный способ, если вы выполняете сортировку по полям в сторонних таблицах. (что я бы не рекомендовал, но иногда это необходимо). Поэтому я думаю, что это все еще очень верный ответ. (вопрос , который задают , как присоединиться к таблицам, красноречивый способ на самом деле никогда не присоединяется к ним в исходном запросе.)
Skeets

этот пакет поможет вам github.com/fico7489/laravel-eloquent-join
fico7489

«Хотя это не очень красноречивый способ сделать это, это единственный способ, если вы сортируете по полям в сторонних таблицах». Скитс, когда вы говорите «единственный способ», вы говорите, что в документах laravel эта важная информация отсутствует?
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]);

Вышеупомянутый запрос содержит ошибку нарушения ограничения целостности, которая была решена в этом ответе
Акшай Кашьяп
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.