Laravel的关系有多少人?

时间:2017-02-27 19:08:47

标签: laravel

我有三个模型:User, Category, Announcement

用户模型:

public function categories()
    {
        return $this->belongsToMany("App\Category");
    }

    public function announcements()
    {
        return $this->hasManyThrough('App\Announcement', 'App\Category');
    }

类别模型:

public function announcements()
    {
        return $this->belongsToMany('App\Announcement');
    }

公告模式:

 public function categories()
    {
        return $this->belongsToMany('App\Category');
    }

我需要通过user_categories表格选择所有公告。

为此我做:

$res = User::where("id", 1)->with("announcements")->get();
dd($res);

结果我得到SQL错误:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'announcements.category_id' in 'on clause' (SQL: select `announcements`.*, `categories`.`user_id` from `announcements` inner join `categories` on `categories`.`id` = `announcements`.`category_id` where `categories`.`user_id` in (1) and `announcements`.`deleted_at` is null)

为什么Laravel会尝试在表格中搜索“`公告. category_id`?

总之,我需要获得用户订阅的类别的所有公告。

表数据库结构:

Users
id | name

Announcements
id | name

categories
category_id | announcement_id 

users_categories
category_id | user_id

所以,我需要通过表users_categories获取所有公告,其中relation此表与categories属于announcement表。

1 个答案:

答案 0 :(得分:1)

你不能急于加载这种关系,因为

  

要执行此查询,Eloquent会检查中间表上的外键。

因此错误

  

SQLSTATE [42S22]:未找到列:1054未知列' announcements.category_id'

因为HasManyThrough()在指定的模型表中查找关系。

我建议你看一下这个帖子: https://laravel.io/forum/05-21-2014-problem-with-eloquents-hasmanythroughs-query

它们向您展示如何编写自己的查询来执行此操作。一个例子是,在用户模型中做

public function getAnnouncements() {
    $announcements = [];
    foreach( $this->categories as $category ) {
        foreach( $category->announcements as $annoucement ) {
            if ( !isset($announcements[$annoucement->id]) ) { //avoid duplicates
                $annoucements[$announcement->id] = $announcement;
            }
        }
    }
}

嵌套的foreach将提供属于与用户相关的类别的所有公告。

改善功能

public function getAnnouncements() {
    $announcements = new Collection();
    foreach( $this->categories as $category ) {
        $announcements->collect($category->announcements);
    }
}