雄辩的关系深度

Posted

技术标签:

【中文标题】雄辩的关系深度【英文标题】:Eloquent relationship depth 【发布时间】:2018-09-16 09:39:07 【问题描述】:

在我的应用中,我有多个关系。用户有很多事件。许多活动有许多参与者。

例如事件模型:

public function participants()

    return $this->belongsToMany('App\Participant');


public function user()

    return $this->belongsTo('App\User');

我想获取所有用户事件参与者并对他们进行分页。

$participants = $user->events->participants; 这显然不起作用,这就是为什么我要尝试这样的事情

$events = $user->events;
$participants = [];
foreach ($events as $event) 
   $participants[] = $event->participants;

return $participants;

这适用于获取数据数组,但我无法使用 DB 分页对其进行分页,因为它是一个数组。

有没有另一种方法可以让所有参与者建立更深层次的关系?或者我还能如何使用 laravel 或 lumen 分页?

编辑:添加迁移

Schema::create('users', function (Blueprint $table) 
    $table->increments('id');
    ...  
);
Schema::create('events', function (Blueprint $table) 
    $table->increments('id');
    ...
);
Schema::create('participants', function (Blueprint $table) 
    $table->increments('id');
    ...   
);
Schema::create('event_participant', function (Blueprint $table) 
    $table->integer('event_id');
    $table->integer('participant_id');
);

编辑 2:我的解决方案: 使参与者排列 Laravel 集合并添加宏方法进行分页,如回答这里https://laracasts.com/discuss/channels/laravel/how-to-paginate-laravel-collection

【问题讨论】:

您要对参与者进行分页吗? @HaiderAli 是的,但仅来自用户事件。 检查这个:laravel.com/docs/5.6/eloquent-relationships#has-many-through return $this->hasManyThrough('App\Participant', 'App\Event'); 这实际上不起作用,因为我在参与者和事件之间有数据透视表。如何让它引用数据透视表而不是在 Participants 表中搜索 event_id? 【参考方案1】:

如果您只想对分页器进行一般访问,这就是我使用的。也许在某个时候会有所帮助。

/**
 * @param $array
 *
 * @return \Illuminate\Pagination\LengthAwarePaginator
 */
public static function makePaginatorForArray(array $array)
    $collection = collect($array);

    return self::makePaginatorForCollection($collection);


/**
 * This should match laravel's built in Model::paginate()
 *
 * @param \Illuminate\Support\Collection $collection
 *
 * @return \Illuminate\Pagination\LengthAwarePaginator
 */
public static function makePaginatorForCollection(\Illuminate\Support\Collection $collection)
    $current_page = (request()->has('page') ? request()->page : 1) - 1;//off by 1 (make zero start)
    $per_page     = (request()->has('per_page') ? request()->per_page : config('pagination.per_page')) * 1;

    if(env('APP_ENV') == 'testing')
        $per_page = 0;
    

    if($per_page)
        $page_data = $collection->slice($current_page * $per_page, $per_page)->all();
    else
        $page_data = $collection->all();
        $per_page  = count($page_data) + 1;
    

    return new \Illuminate\Pagination\LengthAwarePaginator(array_values($page_data), count($collection), $per_page);

要使用这个...

public function myControllerMethod(Request $request)
  $lots_of_data = MyModel::all()->pluck('deeper_data')->flatten();
  return Helpers::makePaginatorForCollection($lots_of_data);

【讨论】:

【参考方案2】:

HasManyThrough 关系最适合这种情况。所以在你的用户模型中添加这个方法:

public function eventsParticipants()

  return $this->hasManyThrough('App\Participant', 'App\Event');

然后您可以使用定义的关系获取用户事件参与者并轻松对其进行分页。

$user = Auth::user(); 
$user->eventsParticipants->paginate(5);

【讨论】:

这实际上不起作用,因为我在参与者和事件之间有数据透视表。我怎样才能让它引用数据透视表而不是像这样在 Participants 表中搜索 event_id? 能否将您的迁移或架构添加到问题中,以便我们查看。 添加迁移【参考方案3】:

这种情况下没有原生关系。

我创建了 HasManyThrough 关系并支持 BelongsToMany: Repository on GitHub

安装后,可以这样使用:

class User extends Model 
    use \Staudenmeir\EloquentHasManyDeep\HasRelationships;

    public function participants() 
        return $this->hasManyDeep(Participant::class, [Event::class, 'event_participant']);
    


$user->participants()->paginate();

【讨论】:

以上是关于雄辩的关系深度的主要内容,如果未能解决你的问题,请参考以下文章

雄辩的,每个表的多个关系

基于关系过滤的雄辩的`with()`

为啥 laravel 雄辩的关系返回空数组

将原始联合查询转换为雄辩的关系

雄辩的关系,模型的链接(Laravel 5.4)

Laravel 雄辩的一对一通过(级别/树)关系