使用自定义数据透视表的高级Eloquent查询

时间:2013-08-03 21:28:30

标签: php laravel laravel-4 eloquent

这是一个适合你的大师。 我有4张桌子。用户,厨师,地点,类型。

用户表

id
etc

厨师表

id
user_id
etc

位置表

id
zip
etc

类型表

id
type_name
etc

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

厨师和用户模型

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

'users'表与'locations'表有很多关系。我还在'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”的所有Chef ID,这是一个位于“locations”表中的字段。 更多信息 - 数据透视表中可用的type_id值之一为'0'。如果成为Chef的用户不想为其Chef帐户创建单独的Location,则表示默认位置。每个用户都有其中一个,对应的pivot(location_user)条目,type_id = 0.如果用户希望单独的位置作为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;

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

*其中一个用户IS也是厨师,但他的Chef帐户使用默认位置(数据透视表中的记录,type_id = 0。没有带有user_id值的枢轴记录,type_id = 2)。*

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

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

尝试:

$locations = Location::with('users.chef') [etc..]
相关问题