繁体   English   中英

带有自定义数据透视表的高级口才查询

[英]Advanced Eloquent query with custom pivot table

这是给您的大师。 我有4张桌子。 用户,厨师,位置,类型。

用户表

id
etc

厨师桌

id
user_id
etc

位置表

id
zip
etc

类型表

id
type_name
etc

创建的每个Chef帐户都是一个用户。 创建的每个用户帐户不一定都是厨师。 还有其他类型,但为简单起见,我省略了。

厨师和用户模型

class Chef extends Eloquent {
    public function user() {
        return $this->belongsTo('User');
    }
}
class User extends Eloquent {
    public function chef() {
        return $this->hasOne('Chef');
    }
}

“用户”表与“位置”表具有多对多关系。 我还在“ location_user”数据透视表中添加了“ type_id”。

location_user数据透视表

id
location_id
user_id
type_id

位置模型

class Location extends Eloquent {
    public function users() {
        return $this->belongsToMany('User')->withTimestamps()->withPivot(['type_id']);
    }
}

我的目标是为特定的“ zip”返回所有厨师ID,该“ zips”位于“ locations”表中。 一点点信息-数据透视表中可用的type_id值之一为“ 0”。 如果代表厨师的用户不想为其厨师帐户创建单独的位置,则这表示默认位置。 每个用户都具有其中之一,即type_id = 0的相应枢轴(location_user)条目。如果用户希望使用单独的Location作为Chef,则将创建单独的“位置”表条目,并由带有type_id的单独枢轴表条目链接= 2.这样,系统便知道要使用哪个位置。 如果为特定用户存在一个Chef帐户,但不附带type_id = 2的透视帐户,则将使用该透视帐户(具有该user_id和type_id = 0)链接到的位置。

这是我的搜索代码的一部分:

        if ($city_search || $zip_search) {
            $chef_ids = array();
            // TODO: Possibly bad for scaling.  Find a single Eloquent call for this
            $locations = Location::with('users')
                ->where('zip', 'LIKE', "%$city_search%")
                ->where('zip', 'LIKE', "%$zip_search%")
                ->get();
            foreach ($locations as $loc) {
                foreach ($loc->users as $user) {
                    $chef_ids[] = $user->chef->id;
                }
            }
        }

        if (count($chef_ids) == 0) return NULL;

问题是,如果单个用户也是一个厨师,其厨师位置为默认位置,但又具有另一个[类型不是厨师]位置,则在透视表中将有2个该用户的记录,一个记录的type_id = 0(同时提供默认位置和Chef位置),另一个具有type_id =?。 如果默认位置不是查询的“ zip”值,而是另一个,则将返回该厨师的ID。 为了清楚起见,流程如下所示:使用zip =?获取所有位置。 从数据透视表中获取所有用户。

*其中一个用户也是Chef,但是他的Chef帐户使用默认位置(数据透视表中type_id = 0的记录。不存在其user_id值和type_id = 2的数据透视记录)。*

从所有这些用户那里获取厨师,然后获取其ID。 该用户是否有一个包含location_id包含查询的zip值的数据透视帐户? 是(另一种类型)。 该用户是否有厨师帐户? 是。 然后,即使他的Chef帐户在另一个zip中使用默认的Location,也会返回他的Chef_id。

有什么建议吗?

尝试:

$locations = Location::with('users.chef') [etc..]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM