简体   繁体   English

Laravel模型在单个查询中实现一对多

[英]Laravel models to implement one to many and many to many in single query

i have this table structure, project has one to many relation with rewards , rewards and shipping has many to many relation with pivot table reward_ship . 我具有这种表结构, projectrewardsone to many关系, rewards and shipping与数据透视表reward_shipmany to many关系。

projects       rewards         shipping       reward_ship
---------      --------        --------       ------------ 
id             id              id             id 
title          amount          location       reward_id
amount         project_id      name           ship_id

i am trying to extract one particular project details with all other associate tables data( rewards and shipping data using reward_ship table) in one query. 我试图在一个查询中提取所有其他关联表数据(使用reward_ship表的rewards and shipping数据)的特定project详细信息。

These is how i am trying 这些就是我正在尝试的方式

Projects Model 项目模型

    class Rewards extends Model {
         public function projs(){
              return $this->hasMany('App\Rewards');
          }
         public function rewds(){
              return $this->belongsToMany('App\Shipping')
              ->withPivot('reward_ship', 'ship_id', 'reward_id');
         }
         public function shiplc(){
               return $this->belongsToMany('App\Rewards')
               ->withPivot('reward_ship', 'ship_id', 'reward_id');
         }
      }
class Rewards extends Model {
    public function proj() {
        return $this->belongsTo('App\Projects');
    }
}

Controller api class 控制器API类

Route::get('projects/{id}', function($id) {
$p = Projects::find($id);
$getd = Rewards::with('proj')
    ->where('rewards.project_id', '=', $p->id)
    ->get();
 }); 

it doesn't work. 它不起作用。 i search and tried many related model base query in larvel. 我在larvel中搜索并尝试了许多相关的模型基础查询。 i know my implementation are wrong. 我知道我的实现是错误的。 Please suggest me to work out. 请建议我锻炼。

You can use Laravel 5.5 new feature API Resources . 您可以使用Laravel 5.5新功能API资源

It helps you to format the output of objects such as models or collections, to display attributes and also relationships. 它可以帮助您格式化诸如模型或集合之类的对象的输出格式,以显示属性以及关系。

So, you could do something like this in your ItemResource: 因此,您可以在ItemResource中执行以下操作:

    <?php

    namespace App\Http\Resources;

    use Illuminate\Http\Resources\Json\Resource;

    class Project extends Resource
    {
        /**
         * Transform the resource into an array.
         *
         * @param  \Illuminate\Http\Request
         * @return array
         */
        public function toArray($request)
        {
            return [
                'project_id' => $this->project_id,
                'title' => $this->title,
                'amount' => $this->amount,
                // To access relationship attributes:
                'rewards' => $this->rewards->load('shippings'),
            ];
        }
    }

Then in your controller, you just need to create a new Resource instance and pass the item object that you want to return: 然后,在您的控制器中,您只需要创建一个新的Resource实例并传递要返回的item对象即可:

use App\Http\Resources\Project as ProjectResource;

// some code

    /**
     * Show a single formatted resource.
     *
     * @param Project $project
     * @return ProjectResource
     */
    public function show($project)
    {
        return new ProjectResource($project);
    }

// the rest of your code

The output should be the expected. 输出应该是预期的。

class Project extends Model
{
    public function rewds()
    {
        return $this->hasMany('App\Rewards');
    }

    public function shiplc()
    {
        return $this->hasManyThrough('App\Shipping', 'App\Rewards');
    }
}

class Rewards extends Model
{
    public function shiplc()
    {
        return $this->belongsToMany('App\Shipping');

    }

    public function projs()
    {
        return $this->belongsTo('App\Project');
    }

}

class Shipping extends Model
{
    public function shiplc()
    {
        return $this->belongsToMany('App\Shipping');

    }
}

Route::get('projects/{id}', function($id) {
    $p = Projects::with(['rewds', 'shiplc'])->find($id);
});

Project.php Project.php

class Project extends Model {
    public function rewards() {
        return this->hasMany(Reward::class, 'project_id', 'id');
    }
}

Reward.php Reward.php

class Reward extends Shipping {
    public function shipping(){
        return $this->belongsToMany(Shipping::class, 'reward_ship', 'reward_id', 'ship_id');
    }

    public function project(){
        return $this->belongsTo(Project::class);
    }
}

You can retrieve it like this: 您可以像这样检索它:

$projectDetails = Project::where('id', $projectId)
                             ->with(['rewards', 'rewards.shipping'])->get();

You have to fix the relationships that you have : 您必须修复所拥有的关系:

Projects Model : 项目型号:

public function rewards(){
    return $this->hasMany('App\Rewards');
}

Rewards Model : 奖励模式:

public function projects() {
    return $this->belongsTo('App\Projects');
}

public function shippings(){
    return $this->belongsToMany('App\Shipping','reward_ship', 'reward_id', 'ship_id');
}

Shipping model: 运送方式:

public function rewards(){
    return $this->belongsToMany('App\Rewards','reward_ship', 'ship_id', 'reward_id');
}

After that you can call the relationships in the controller to eager load the wanted elements like this : 之后,您可以调用控制器中的关系以急于加载所需的元素,如下所示:

$project = Projects::with('rewards.shippings')
                    ->where('id', $project_id)
                    ->get();

And in the view you can loop over the rewards then get the shippings like this : 在视图中,您可以遍历奖励,然后像这样获得运输:

@foreach ($project->rewards as $reward)
    <p>This is a reword {{ $reward->amount }}</p>
    @foreach ($reward->shippings as $shipping)
        <p>This is a shipping {{ $shipping->name }}</p>
    @endforeach 
@endforeach 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM