首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有许多穿透

有许多穿透
EN

Stack Overflow用户
提问于 2015-08-01 18:26:32
回答 1查看 100关注 0票数 2

一个Venue有多个Subscriptions

一个Subscription有多个Subscribers (User)。

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

如何从Venue获取所有Subscribers

我已经尝试过了:

代码语言:javascript
复制
class Venue {
    /**
     * Members
     */

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

但它失败了,并出现MySQL错误:

代码语言:javascript
复制
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)

订阅模型的外观:

代码语言:javascript
复制
`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');
        }

}
EN

回答 1

Stack Overflow用户

发布于 2015-08-04 02:05:47

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

代码语言:javascript
复制
class User {
    public function venues() {
        return $this->belongsToMany('App\Venue');
    }
}

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

这个星座实际上需要三个表,它们是(我为每个模型提供了一个列name):

代码语言:javascript
复制
users
  - id
  - name

venues
  - id
  - name

user_venue
  - user_id
  - venue_id

但要访问这些关系,您可以简单地使用雄辩的魔术:

代码语言:javascript
复制
// 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();

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

代码语言:javascript
复制
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列,它应该可以工作。如果您有第三个模型需要与其他两个模型的连接连接,这可能会有所帮助,但通常不会发生这种情况。因此,首先尝试使用数据透视表,如上图所示。

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

代码语言:javascript
复制
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;
     }
}

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

代码语言:javascript
复制
Venue::find($id)->members()->get()
// or with duplicate members
Venue::find($id)->members(false)->get()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31760807

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档