如何在同一资源LARAVEL中返回数据透视表的数据

Posted

技术标签:

【中文标题】如何在同一资源LARAVEL中返回数据透视表的数据【英文标题】:How to return the data of a pivot table in the same resource LARAVEL 【发布时间】:2019-12-01 23:21:40 【问题描述】:

我有一个关于LARAVEL API 的小问题。如何在同一资源中返回和连接数据透视表的数据?我有 3 个表、库存、产品和库存产品。最后一张表有库存和价格数据(产品的,因为它们因库存而异),我想列出产品并显示价格和库存(来自数据透视表)

我上传了产品控制器、库存和产品模型以及产品资源。顺便说一句,正如我现在所做的那样,价格和股票返回 null。

到目前为止,在我的 ProductController 中:

public function index()

   return ProductResource::collection(Product::with('inventories')->paginate(25));

在我的产品模型中:

class Product extends Model
    
    public function inventories()
           
        return $this->belongsToMany('App\Inventory','inventory_product')->withPivot('price','stock')->withTimestamps();     
    

在我的库存模型中:

class Inventory extends Model
   
    public function products()
      
        return $this->belongsToMany('App\Product','inventory_product')->withPivot('price','stock')->withTimestamps();        
    

在我的产品资源中:

public function toArray($request)

    return [
        'id'=>$this->id,
        'name'=>$this->name,
        'description'=>$this->description,
        'short_description'=>$this->short_description,
        'category'=>$this->category,//category_id
        'url'=>$this->url,
        'image'=>$this->image,
        'relevant'=>$this->relevant,
        'month'=>$this->month,
        'price'=>$this->price,
        'stock'=>$this->stock
    ];

我的迁移清单表:

Schema::create('inventories', function (Blueprint $table) 

    $table->increments('id');
    $table->string('name');
    $table->unsignedInteger('city_id');
    $table->timestamps();
    $table-> foreign('city_id')->references('id')->on('cities')->onDelete('cascade');
);

我的迁移产品表:

Schema::create('products', function (Blueprint $table) 

    $table->increments('id');
    $table ->string('name');
    //$table ->integer('stock');
    $table ->string('description');
    $table ->string('short_description');
    $table ->unsignedInteger('category');//category_id
    //$table ->integer('price');
    $table ->string('url');
    $table ->string('image');
    $table ->boolean('relevant');
    $table ->boolean('month');
    $table->timestamps();
    $table-> foreign('category')->references('id')->on('categories')->onDelete('cascade');
);

还有我的 inventory_product 迁移表:

$table->increments('id');
    $table->integer('inventory_id')->unsigned();
    $table->integer('product_id')->unsigned();
    $table ->integer('price');
    $table ->integer('stock');
    $table->timestamps();
    $table-> foreign('inventory_id')->references('id')->on('inventories')->onDelete('cascade');
    $table-> foreign('product_id')->references('id')->on('products')->onDelete('cascade');

这样,我得到:


    "id": 1,
    //staff on product,
    "price": null,
    "stock": null

我应该得到:


    "id": 1,
    //staff on product,
    "price": 123,//data on the pivot table
    "stock": 123//data on the pivot table

编辑:实际上我应该得到类似的东西:


    "id": 1,
    //staff on product,
[
    "inventory_id": 1,//data on the pivot table
    "price": 123,//data on the pivot table
    "stock": 123//data on the pivot table
]
[
    "inventory_id": 2,//data on the pivot table
    "price": 333,//data on the pivot table
    "stock": 333//data on the pivot table
]


如果产品存在多个库存,对吗?

提前谢谢你:)

【问题讨论】:

您是否确认任何一种模型的关系都按预期工作?例如。通过在修补程序中运行Product::first()->inventories()->get() 【参考方案1】:

我认为问题在于您的 index() 函数试图返回一个产品模型的集合,该集合只有该模型的参数。如果您只想要整个数组,您可以对该集合进行连接:

https://laravel.com/docs/5.8/queries#joins

【讨论】:

没关系,这个链接里有答案。你能放一些代码吗? 我正在阅读有关 'price'=>$this->pivot->price, 'stock'=>$this->pivot->stock, 方法,而不是使用连接,你怎么办认为?【参考方案2】:

您的产品可能在超过 1 个库存中,您无法确定您从哪个库存中获取商品,您可以使用 $this->inventories 访问它 放你不需要那个, 答案取决于您的逻辑,如果 1 件产品可能超过库存,您应该退回库存的集合或汇总库存或您需要查看的任何内容, 如果 1 个库存中存在 1 个产品,您应该将函数编辑为 belongsTo 并且您的代码应该可以工作

【讨论】:

你说得对,是多对多关系,但是检查我刚刚制作的编辑部分,我需要列出产品及其价格和库存,编辑更有意义 试试这个``` public function toArray($request) return [ 'id'=>$this->id, 'name'=>$this->name, 'description'=> $this->description, 'short_description'=>$this->short_description, 'category'=>$this->category,//category_id 'url'=>$this->url, 'image'=>$this- >image, 'relevant'=>$this->relevant, 'month'=>$this->month, 'inventories'=>$this->inventories ]; ```【参考方案3】:

你们的关系是多对多的 如果您需要访问此关系的数据透视表,可以从相关行获取一个产品和第一个相关库存或其他相关行,而不是访问数据透视表 例如 在您的资源中

public function toArray($request)

    return [
        'id'=>$this->id,
        'name'=>$this->name,
        'description'=>$this->description,
        'short_description'=>$this->short_description,
        'category'=>$this->category,//category_id
        'url'=>$this->url,
        'image'=>$this->image,
        'relevant'=>$this->relevant,
        'month'=>$this->month,
        'price'=>$this->inventories->first->price,
        'stock'=>$this->inventories->first->stock
    ];


【讨论】:

你能看一下编辑部分吗,我知道结构可能会改变,因为我需要返回整个库存内容,以及 id 你可以像这样使用地图` $newInventories=$this->inventories->map->function($inventori) return [ "inventory_id": $inventori->id, "price": $inventori->pivot->price, "stock": $inventori->pivot->stock, ] ` 然后作为回报 ``` return [ 'id'=>$this->id, 'name'=>$ this->name, 'inventories'=>$newInventories ];

以上是关于如何在同一资源LARAVEL中返回数据透视表的数据的主要内容,如果未能解决你的问题,请参考以下文章

在 Laravel 4 中查询数据透视表

Laravel 如何创建数据透视表?

laravel 使用具有多对多关系数据透视表的策略

laravel 检索值匹配数据透视表的所有用户

数据透视表的laravel关系问题

如何创建数据透视表 laravel?