php - 定义联接时进行验证

标签 php laravel-5.3

我试图定义一个验证,只包括满足特定条件的用户 - 主要是考虑其元数据(存储在另一个表中)具有字段 supplier_id 的用户值(value)。因此,我在 UpdateXRequest 类中完成了此操作:

public function rules()
{
     $journey = $this->route()->parameter('journey');

     return ['driver_id' => [
          Rule::exists('users', 'id')
               ->where(function($query) use ($journey){
                     $query->join('users_meta', 'users.id', '=', 'users_meta.user_id')
                         ->where('users_meta.key', 'supplier_id')
                         ->where('users_meta.value', $journey->supplier_id);
               })
          ]
     ];
}

但是,我得到 Column not found: 1054 Unknown column 'users_meta.key' in 'where clause' (SQL: select count(*) as aggregate from users where id = x and (users_meta.key = supplier_id 和 users_meta.value = y)) 错误。

我怎样才能做到这一点?


我正在寻找使用默认 Laravel 逻辑的答案,而不是编写我自己的验证器


根据请求,这里是架构查询:

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(10) unsigned NOT NULL,
  `email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `password` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  `role_id` int(10) unsigned NOT NULL
);

CREATE TABLE IF NOT EXISTS `users_meta` (
  `id` int(10) unsigned NOT NULL,
  `user_id` int(10) unsigned NOT NULL,
  `type` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'null',
  `key` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `value` text COLLATE utf8_unicode_ci,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL
);

ALTER TABLE `users`
  ADD PRIMARY KEY (`id`),
  ADD UNIQUE KEY `users_email_unique` (`email`);

ALTER TABLE `users`
  MODIFY `id` int(10) unsigned NOT NULL AUTO_INCREMENT;

ALTER TABLE `users_meta`
  ADD PRIMARY KEY (`id`),
  ADD KEY `users_meta_user_id_index` (`user_id`),
  ADD KEY `users_meta_key_index` (`key`);

ALTER TABLE `users_meta`
  MODIFY `id` int(10) unsigned NOT NULL AUTO_INCREMENT;

INSERT INTO `users` (`id`, `email`, `password`, `created_at`, `updated_at`, `role_id`) VALUES (6898, 'a@b.com', '', '2017-08-09 12:15:05', '2017-08-09 13:19:56', 4);

INSERT INTO `users_meta` (`id`, `user_id`, `type`, `key`, `value`, `created_at`, `updated_at`) VALUES (18, 6898, 'string', 'supplier_id', '6897', '2017-08-09 12:15:05', '2017-08-09 12:15:05');

查询存在于 OP 中,但每个请求添加了从查询日志中生成的 SQL 查询:

select count(*) as aggregate from `users` where `id` = 7011 and (`users_meta`.`key` = supplier_id and `users_meta`.`value` = 6897)

仔细想想,为什么它不起作用是完全合理的——内部 join 没有任何条件(它没有出现在查询日志中仍然很奇怪 -也许这是 Laravel 所做的优化,避免不必要地为 where 而不是 select 连接表)。内部 where 目前在 users 上运行,而不是在来自 join 的表上运行 - 根据 https://laravel.com/docs/5.4/queries#joins (高级连接子句),它们需要在 join 内部才能工作(根据@DarkMukke 的回答)

最佳答案

不是 100% 肯定,但从逻辑上讲,这听起来像是你的连接的 where 条件应该在闭包中

public function rules()
{
    $journey = $this->route()->parameter('journey');

    return ['driver_id' => [
        Rule::exists('users', 'id')
            ->where(function($query) use ($journey){
                $query->join('users_meta', function ($join) use ($journey) {
                    $join->on('users.id', '=', 'users_meta.user_id')
                        ->where('users_meta.key', 'supplier_id')
                        ->where('users_meta.value', $journey->supplier_id);
                });
            })
        ]
    ];
}

即使那样,您也可能不需要第一个闭包,例如 我错了,where 与规则的条件有关,而不是查询构建器的 where 条件。

编辑:我没有尝试过这段代码,但根据我的经验,以及对文档的一些双重检查,这应该是正确的。

此外,由于条件都在连接上,您可以通过添加条件而不是连接更少的数据来加快速度

public function rules()
{
    $journey = $this->route()->parameter('journey');

    return [
        'driver_id' => [
            Rule::exists('users', 'id')
                ->where(function ($query) use ($journey) {
                    $query->join('users_meta', function ($join) use ($journey) {
                        $join->on('users.id', '=', 'users_meta.user_id')
                            ->on('users_meta.key', '=', 'supplier_id')
                            ->on('users_meta.value', '=', $journey->supplier_id);
                    });
                })
        ]
    ];
}

关于php - 定义联接时进行验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45941355/

相关文章:

php - 如何在 PDO 中编写下面的代码

php - 在 PHP 中,为什么 imagecreatefromjpeg "not a jpeg file"更改为 fatal error ?

php - 检查 session 是否设置,如果没有创建一个?

php artisan make :controller Command not working in Laravel 5. 3 模块应用程序

php - Laravel全局中间件获取不到session

laravel - laravel 中的 Auth::login($user) 无法登录用户

php - Laravel 5.3 - 图像验证不工作

php - 在 laravel 框架内运行独立的 .php

php - 阻止 Controller 执行

php - 如果条件匹配,数据库选择一个公共(public)字段