【问题标题】: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 是的,但仅来自用户事件。
  • return $this->hasManyThrough('App\Participant', 'App\Event'); 这实际上不起作用,因为我在参与者和事件之间有数据透视表。如何让它引用数据透视表而不是在 Participants 表中搜索 event_id?

标签: php laravel eloquent lumen


【解决方案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();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-15
      • 1970-01-01
      • 1970-01-01
      • 2014-08-27
      相关资源
      最近更新 更多