Laravel Eloquent 多对多如何

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15809319/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 07:40:07  来源:igfitidea点击:

Laravel Eloquent Many to Many how to

phprelationshiplaravellaravel-4eloquent

提问by Crinsane

I'm trying to learn Laravel and right now I'm experimenting with Eloquent. I've got the following case that I can't solve right now:

我正在尝试学习 Laravel,现在我正在试验 Eloquent。我有以下情况,我现在无法解决:

Let's say I'm creating a webshop, so I have products (Product 1, Product 2, etc):

假设我正在创建一个网上商店,所以我有产品(产品 1、产品 2 等):

+-------------+------------------+------+-----+---------------------+----------------+
| Field       | Type             | Null | Key | Default             | Extra          |
+-------------+------------------+------+-----+---------------------+----------------+
| id          | int(10) unsigned | NO   | PRI | NULL                | auto_increment |
| name        | varchar(255)     | NO   |     | NULL                |                |
| slug        | varchar(255)     | NO   |     | NULL                |                |
| description | text             | NO   |     | NULL                |                |
| price       | decimal(5,2)     | NO   |     | NULL                |                |
| active      | tinyint(4)       | NO   |     | 1                   |                |
| created_at  | timestamp        | NO   |     | 0000-00-00 00:00:00 |                |
| updated_at  | timestamp        | NO   |     | 0000-00-00 00:00:00 |                |
+-------------+------------------+------+-----+---------------------+----------------+

Those products are sorted into Taxonomies (Brand, Color, Department):

这些产品按分类法(品牌、颜色、部门)分类:

+-------------+------------------+------+-----+---------------------+----------------+
| Field       | Type             | Null | Key | Default             | Extra          |
+-------------+------------------+------+-----+---------------------+----------------+
| id          | int(10) unsigned | NO   | PRI | NULL                | auto_increment |
| name        | varchar(255)     | NO   |     | NULL                |                |
| slug        | varchar(255)     | NO   |     | NULL                |                |
| description | text             | NO   |     | NULL                |                |
| created_at  | timestamp        | NO   |     | 0000-00-00 00:00:00 |                |
| updated_at  | timestamp        | NO   |     | 0000-00-00 00:00:00 |                |
+-------------+------------------+------+-----+---------------------+----------------+

These taxonomies have terms (Nike, Adidas, Red, Green, Boys, Girls):

这些分类法有术语(耐克、阿迪达斯、红色、绿色、男孩、女孩):

+-------------+------------------+------+-----+---------------------+----------------+
| Field       | Type             | Null | Key | Default             | Extra          |
+-------------+------------------+------+-----+---------------------+----------------+
| id          | int(10) unsigned | NO   | PRI | NULL                | auto_increment |
| taxonomy_id | int(11)          | NO   |     | NULL                |                |
| name        | varchar(255)     | NO   |     | NULL                |                |
| slug        | varchar(255)     | NO   |     | NULL                |                |
| description | text             | NO   |     | NULL                |                |
| created_at  | timestamp        | NO   |     | 0000-00-00 00:00:00 |                |
| updated_at  | timestamp        | NO   |     | 0000-00-00 00:00:00 |                |
+-------------+------------------+------+-----+---------------------+----------------+

And last I have a pivot table to connect the terms to the products:

最后,我有一个数据透视表将术语连接到产品:

+------------+------------------+------+-----+---------------------+----------------+
| Field      | Type             | Null | Key | Default             | Extra          |
+------------+------------------+------+-----+---------------------+----------------+
| id         | int(10) unsigned | NO   | PRI | NULL                | auto_increment |
| product_id | int(11)          | NO   |     | NULL                |                |
| term_id    | int(11)          | NO   |     | NULL                |                |
| created_at | timestamp        | NO   |     | 0000-00-00 00:00:00 |                |
| updated_at | timestamp        | NO   |     | 0000-00-00 00:00:00 |                |
+------------+------------------+------+-----+---------------------+----------------+

I've created models for Product, Taxonomy and Term like this:

我已经为产品、分类法和术语创建了如下模型:

<?php

class Product extends Eloquent {

    public function terms()
    {
        return $this->belongsToMany('Term', 'product_terms', 'product_id', 'term_id');
    }

}

<?php

class Taxonomy extends Eloquent {

    public function terms()
    {
        return $this->hasMany('Term');
    }

}

<?php

class Term extends Eloquent {

    public function taxonomy()
    {
        return $this->belongsTo('Taxonomy');
    }

}

Now I want to do the following, I want to get all the products, loop over them and show something like the name, description and price. Well, a simple $products = Product::all();is all I need. Then, when I loop over the products, I know I can do something like $product->termsto get all the terms. But how should a get the term of a given taxonomy. So for example something like this:

现在我想执行以下操作,我想获取所有产品,遍历它们并显示名称、描述和价格等内容。嗯,一个简单的$products = Product::all();就是我所需要的。然后,当我遍历产品时,我知道我可以做一些事情$product->terms来获取所有条款。但是应该如何获得给定分类法的术语。因此,例如这样的事情:

<?php
echo $product->term('brand'); // Where 'brand' is the taxonomy name of the term I want to get
echo $product->term('color'); // Where 'color' is the taxonomy name of the term I want to get

Hope someone can help me.

希望可以有人帮帮我。

回答by Beau

Alright, I thinkI understand your setup. Given the relations you stated, I think you'd define your models as follows:

好的,我我明白你的设置了。鉴于您所说的关系,我认为您可以按如下方式定义您的模型:

<?php

class Product extends Eloquent {

    public function terms()
    {
        return $this->belongsToMany('Term')->withTimestamps();
    }

}

<?php

class Taxonomy extends Eloquent {

    public function terms()
    {
        return $this->hasMany('Term');
    }

}

<?php

class Term extends Eloquent {

    public function taxonomy()
    {
        return $this->belongsTo('Taxonomy');
    }

    public function products()
    {
        return $this->belongsToMany('Product')->withTimestamps();
    }

}

Since your pivot is named and id'd correctly you shouldn't have to specify that info in the belongsToMany relationship, but if you want the timestamps to work you need the withTimestamps.

由于您的数据透视表已正确命名和标识,因此您不必在belongsToMany 关系中指定该信息,但如果您希望时间戳起作用,则需要 withTimestamps。

EDIT:

编辑:

If you can look taxonomies up by id instead of slug, this will work:

如果您可以通过 id 而不是 slug 查看分类法,这将起作用:

$products = Product::all();
foreach($products as $product)
{
    $term = $product->terms()->with('taxonomy')->where('taxonomy_id', '=', 2)->first();
    echo $term->name;
}

In the scenario above you could just store the taxonomy slug in the term table since it should be a unique key. Otherwise you could look over the terms and look for the one with the taxonomy that you want:

在上面的场景中,您可以将分类标头存储在术语表中,因为它应该是一个唯一的键。否则,您可以查看这些术语并查找具有您想要的分类法的术语:

$products = Product::all();
foreach($products as $product)
{
    $terms = $product->terms()->with('taxonomy')->get();
    foreach($terms as $term)
    {
        if($term->taxonomy->slug == 'brand')
        {
            echo $term->name."<br />";
        }
    }
}

END EDIT

结束编辑

I have to admit that I'm a little lost though because your last two tables seem exactly the same and I'm wondering why you associate terms with products instead of taxonomies with products. I'm suspect that my solution won't work with the way you're relating things but if you related taxonomies with products instead it would work jut fine.

我不得不承认我有点迷茫,因为你的最后两个表格看起来完全一样,我想知道为什么你将术语与产品而不是分类法与产品相关联。我怀疑我的解决方案不适用于您关联事物的方式,但是如果您将分类法与产品相关联,它会很好地工作。

<?php
$product->taxonomy()->where('slug', '=', 'brand')->term;