有很多通过

时间:2015-08-01 10:26:32

标签: php laravel laravel-5 eloquent

Venue有很多Subscriptions

Subscription有许多SubscribersUser)。

Theres一个数据透视表,包含user_id和subscription_id之间的关系。

Pivot for subscription and user_id

如何从Subscribers获取所有Venue

我尝试过:

class Venue {
    /**
     * Members
     */

        public function members() {
            return $this->hasManyThrough('App\User', 'App\Subscription');
        }
}

但它因MySQL错误而失败:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'users.subscription_id' in 'on clause' (SQL: select `users`.*, `sub
    scriptions`.`venue_id` from `users` inner join `subscriptions` on `subscriptions`.`id` = `users`.`subscription_id` where `
    users`.`deleted_at` is null and `subscriptions`.`venue_id` = 1)

我的订阅模型的外观:

`Subscription`

class Subscription extends Model {

    protected $table = 'subscriptions';

    /**
     * Subscripers
     */

        public function subscribers() {
            return $this->belongsToMany('App\User');
        }

    /**
     * Venue
     */

        public function venue() {
            return $this->belongsTo('Venue');
        }

}

1 个答案:

答案 0 :(得分:0)

简单问题:为什么要为Subscriptions使用第三个模型?这听起来像UserVenue之间的正常n:m关系,如上面的评论中所述。

class User {
    public function venues() {
        return $this->belongsToMany('App\Venue');
    }
}

class Venue {
    public function users() {
        return $this->belongsToMany('App\User');
    }
}

这个星座实际上需要三个表,(我给每个模型一个列name):

users
  - id
  - name

venues
  - id
  - name

user_venue
  - user_id
  - venue_id

但是要访问关系,你可以简单地使用Eloquent魔法:

// List of all venues (as Venue models) that are in relation with User with id $id
$venues = User::find($id)->venues()->get();

// Returns the alphabetically first user that has a relation with Venue with id $id
$user = Venue::find($id)->users()->orderBy('name', 'asc')->first();

如果您需要在数据透视表中存储其他信息(例如,在建立关系时),您可以使用其他数据透视表字段:

user_venue
  - user_id
  - venue_id
  - created_at

class User {
    public function venues() {
        return $this->belongsToMany('App\Venue')->withPivot('created_at');
    }
}

class Venue {
    public function users() {
        return $this->belongsToMany('App\User')->withPivot('created_at');
    }
}

// Returns the date of the relations establishment for the alphabetically
// first Venue the User with id $id has a relation to
$created_at = User::find($id)->venues()->orderBy('name', 'asc')->first()->pivot->created_at;

我从未试图做任何你想做的事情,因为它(在目前的信息中)似乎在概念上是错误的。我也不知道是否可以为数据透视表设置自己的模型,但我认为如果数据透视表有自己的主要ID列,它应该可以工作。如果您的第三个模型需要与另外两个模型连接,那么它可能会有所帮助,但通常情况并非如此。所以首先尝试使用数据透视表,如上所示。

好吧,我仍然没有看到一个很好的用例,但我可以为您提供一个有效的查询。不幸的是,我无法让Eloquent查询工作,但解决方案应该仍然没问题。

class Venue {
    public function members($distinct = true) {
        $query = User::select('users.*')
            ->join('subscription_user', 'subscription_user.user_id', '=', 'users.id')
            ->join('subscriptions', 'subscriptions.id', '=', 'subscription_user.subscription_id')
            ->where('subscriptions.venue_id', '=', $this->id);
         if($distinct === true) {
             $query->distinct();
         }
         return $query;
     }
}

可以像平常一样查询关系:

Venue::find($id)->members()->get()
// or with duplicate members
Venue::find($id)->members(false)->get()