Laravel 8 多对多关系不起作用(没有抛出错误)

Posted

技术标签:

【中文标题】Laravel 8 多对多关系不起作用(没有抛出错误)【英文标题】:Laravel 8 Many to Many relationship not working (no errors being thrown) 【发布时间】:2021-06-24 08:12:52 【问题描述】:

我是 Laravel 的新手,但遇到了一个非常奇怪的问题。

我成功地为 6 个表创建了模型和迁移以处理多对多关系。其中一个关系工作正常,我可以通过路由检索数据。然而,另一个只返回一个白屏(没有错误,没有任何东西)。网络选项卡响应说:“此请求没有可用的响应数据” - 但我已经三次检查数据库并搜索不同的记录,但它从未返回任何结果。

我使信息尽可能简单,并遵循所有命名约定。

知道这里发生了什么吗?是不是配置有问题?请帮助我不要发疯 - 我已经尝试了大量的代码迭代,但似乎没有任何工作可以建立多对多的客户端/网络关系。

非工作关系

客户表:

+----------------+-----------------+------+-----+---------+----------------+
| Field          | Type            | Null | Key | Default | Extra          |
+----------------+-----------------+------+-----+---------+----------------+
| id             | bigint unsigned | NO   | PRI | NULL    | auto_increment |
| client_name    | varchar(255)    | NO   |     | NULL    |                |
| client_type_id | bigint unsigned | YES  |     | NULL    |                |
| address        | varchar(255)    | YES  |     | NULL    |                |
| address_2      | varchar(255)    | YES  |     | NULL    |                |
| city           | varchar(255)    | YES  |     | NULL    |                |
| state          | varchar(255)    | YES  |     | NULL    |                |
| zip_code       | varchar(255)    | YES  |     | NULL    |                |
| country        | varchar(255)    | YES  |     | NULL    |                |
| created_at     | timestamp       | YES  |     | NULL    |                |
| updated_at     | timestamp       | YES  |     | NULL    |                |
+----------------+-----------------+------+-----+---------+----------------+

网络表:

+--------------+-----------------+------+-----+---------+----------------+
| Field        | Type            | Null | Key | Default | Extra          |
+--------------+-----------------+------+-----+---------+----------------+
| id           | bigint unsigned | NO   | PRI | NULL    | auto_increment |
| network_name | varchar(255)    | NO   |     | NULL    |                |
| created_at   | timestamp       | YES  |     | NULL    |                |
| updated_at   | timestamp       | YES  |     | NULL    |                |
+--------------+-----------------+------+-----+---------+----------------+

client_network 表:

+------------+-----------------+------+-----+---------+----------------+
| Field      | Type            | Null | Key | Default | Extra          |
+------------+-----------------+------+-----+---------+----------------+
| id         | bigint unsigned | NO   | PRI | NULL    | auto_increment |
| client_id  | bigint unsigned | NO   |     | NULL    |                |
| network_id | bigint unsigned | NO   |     | NULL    |                |
| created_at | timestamp       | YES  |     | NULL    |                |
| updated_at | timestamp       | YES  |     | NULL    |                |
+------------+-----------------+------+-----+---------+----------------+

客户端模型:

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Client extends Model

    use HasFactory;

    public function networks()
    
        return $this->belongsToMany(Network::class);
    

网络模型:

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Network extends Model

    use HasFactory;

    public function clients()
    
        return $this->belongsToMany(Client::class);
    

路线:

Route::get('/testclient', function() 
    $network = Client::find(1)->network_name;
    return $network;
);

【问题讨论】:

您好!只是为了确保,一个帖子属于许多 cmets?我会按照维基所说的那样做,一对多(和反向)关系,这样一个帖子就有很多 cmets,很多 cmets 可以属于一个帖子! laravel.com/docs/8.x/eloquent-relationships#one-to-many 如果你尝试这样:$network = Client::find(1);返回 $network->client(); @Prospero 引发“错误方法”错误。加上帖子/评论关系的其他模型/方法工作正常。 个人推荐,不要命名单数,什么是多资源。如果您的clients 可以有多个networks,反之亦然,请不要将关系命名为client()network(),因为它们将返回collection,但如果您将它们读为单数,您希望得到一个改为模型...您也可以dd(Client::find(1)->network); 并分享结果。 @matiaslauriti 拍摄...我还差 2 个声望点来支持您的评论。一旦我到达那里,我会的。同时,我会添加答案。再次感谢! 【参考方案1】:

对于任何处理类似问题的人来说,这种情况下的问题不是关系,而是从关系中提取数据的路径。

无效路线

Route::get('/testclient', function() 
    $network = Client::find(1)->network_name;
    return $network;
);

工作路线

Route::get('/testing', function()

    $networks = Client::find(1)->networks;

    foreach($networks as $network)

        $network_arr[] = $network->network_name;

    

    return $network_arr;

为解决此问题,cmets 中的建议代码有助于表明数据确实是从关系中提取的,但未正确显示。

助手代码:

dd(Network::find(1)->clients);

【讨论】:

如果您将foreach 更改为map,您可以获得更“laravel 方式”的代码,您应该以执行此操作的函数结尾:return $network->network_name;,它会自动以另一个结尾收藏。如果您需要一个数组,那么您可以使用->toArray(),但如果您要迭代该集合,则无需将其强制转换为数组。【参考方案2】:

你打错字了,改一下

Route::get('/testclient', function() 
    $network = Client::find(1)->network;
    return $network;
);

Route::get('/testclient', function() 
    $network = Client::find(1)->networks; //Add s
    return $network;
);

【讨论】:

感谢您的建议,但仍然没有返回任何数据。我已经更改了上面的 Route 以反映当前的迭代。

以上是关于Laravel 8 多对多关系不起作用(没有抛出错误)的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 多对多关系不起作用

Laravel Nova 多态多对多关系不起作用

博客上的 Laravel 5.1 多对多标签不起作用

NSFetchedResultsController 和多对多关系不起作用

laravel hasmanythrough on manytomany

记录多对多关系 Laravel 8