【问题标题】:Laravel Eloquent Many to Many how toLaravel Eloquent 多对多如何
【发布时间】:2013-03-26 09:58:55
【问题描述】:

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

假设我正在创建一个网上商店,所以我有产品(产品 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 |                |
+-------------+------------------+------+-----+---------------------+----------------+

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

+-------------+------------------+------+-----+---------------------+----------------+
| 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 |                |
+-------------+------------------+------+-----+---------------------+----------------+

这些分类有术语(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 |                |
+-------------+------------------+------+-----+---------------------+----------------+

最后我有一个数据透视表来将术语与产品联系起来:

+------------+------------------+------+-----+---------------------+----------------+
| 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 |                |
+------------+------------------+------+-----+---------------------+----------------+

我已经为产品、分类和术语创建了这样的模型:

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

}

现在我想做以下事情,我想获取所有产品,遍历它们并显示名称、描述和价格等内容。 好吧,我只需要一个简单的$products = Product::all();。 然后,当我循环浏览产品时,我知道我可以执行$product-&gt;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

希望有人可以帮助我。

【问题讨论】:

    标签: php relationship laravel laravel-4 eloquent


    【解决方案1】:

    好的,我认为我了解您的设置。鉴于您所说的关系,我认为您将模型定义如下:

    <?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();
        }
    
    }
    

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

    编辑:

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

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

    在上面的场景中,您可以将分类 slug 存储在术语表中,因为它应该是唯一的键。否则,您可以查看术语并查找具有所需分类的术语:

    $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 />";
            }
        }
    }
    

    结束编辑

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

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

    【讨论】:

    • 谢谢你的回答,我今天晚些时候去看看。但只是快速澄清一下,为什么我有与产品相关的条款。分类只是一组术语的名称。你有像“红、蓝、绿、黄”这样的术语,这些术语的分类是“颜色”。对于一个产品,我想获得它拥有的“条款”。不是它拥有的分类法。因为通常情况下,产品将具有所有分类法。我对它具有给定分类法的哪些术语感兴趣。 “产品是什么颜色”,“产品是什么品牌”
    • 哦,顺便说一句,最后两张表确实一样,但这是一个错误,马上更新。
    • 我无法让它工作。得到这个错误:Call to undefined method Illuminate\Database\Query\Builder::taxonomy()
    • 对,每个产品都有一堆分类法,每个分类法都有一个术语。因为您想了解“产品是什么颜色”之类的信息,所以您希望将分类法与产品而非术语相关联。出于好奇,如果去掉括号,它会起作用吗? $product->terms->taxonomy()->where('slug', '=', 'brand')->first();或 $product->terms()->taxonomy->where('slug', '=', 'brand')->first();或 $product->terms->taxonomy->where('slug', '=', 'brand')->first();或从头开始。
    • 是的,但是如果我将产品与分类相关联。我怎么知道这个词?我会问“产品 1 有哪些分类法”,我会得到“颜色、品牌、部门等”。不是 "red, Nike, Ladies" 删除括号会给我同样的错误,只是这次是关于未定义的关系:Notice: Undefined property: Illuminate\Database\Eloquent\Relations\BelongsToMany::$taxonomy
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-28
    • 2019-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-30
    相关资源
    最近更新 更多