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

时间:2017-11-15 18:29:28

标签: php laravel eloquent

我有这个表结构,projectone to manyrewards个关系,rewards and shipping与数据透视表many to manyreward_ship关系。

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

我正在尝试在一个查询中使用所有其他关联表数据(project数据使用rewards and shipping表)提取一个特定的reward_ship详细信息。

这就是我的尝试

项目模型

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

控制器api类

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

它不起作用。 我在larvel中搜索并尝试了许多相关的模型库查询。 我知道我的实施是错误的。请建议我解决。

4 个答案:

答案 0 :(得分:2)

您可以使用Laravel 5.5新功能API Resources

它可以帮助您格式化对象(如模型或集合)的输出,以显示属性和关系。

所以,你可以在你的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'),
            ];
        }
    }

然后在你的控制器中,你只需要创建一个新的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

输出应该是预期的。

答案 1 :(得分:1)

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

答案 2 :(得分:1)

Project.php

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

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

您可以像这样检索它:

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

答案 3 :(得分:1)

你必须修复你拥有的关系:

项目模型:

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

奖励模型:

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

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

送货模式:

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

之后你可以调用控制器中的关系来急切加载想要的元素,如下所示:

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

在视图中,您可以循环获得奖励,然后获得这样的信息:

@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