laravel где имеет странные результаты

модель продукта

    public function country() {
        return $this->hasMany('App\Models\ProductCountry', 'product_id', 'id');
    }

контроллер

$product = Product::where('mall_' . $this->mall_id, '=', 1)
    ->whereHas('country', function ($i) use ($me) {
        return $i->where('country_id', $me->country_id);
    })
    ->find($key);

необработанный SQL:

select * from `product` where `mall_3` = '1' and exists (select * from `product_country` where `product_country`.`product_id` = `product`.`id` and `country_id` = '109') and `product`.`id` = '3' and `product`.`deleted_at` is null limit 1

выше SQL не возвращает результатов (когда идентификатор продукта = 3

ниже SQL возвращает правильный результат (когда идентификатор продукта = 6)

select * from `product` where `mall_3` = '1' and exists (select * from `product_country` where `product_country`.`product_id` = `product`.`id` and `country_id` = '109') and `product`.`id` = '6' and `product`.`deleted_at` is null limit 1

понятия не имею, запрос вроде не проблема

В предыдущем проекте у меня тоже были эти проблемы, в конце я снова использую поиск и цикл вместо использования whereHas, но на этот раз я снова сталкиваюсь с этой проблемой и пытаюсь выяснить, почему, но несколько часов потрачены впустую, до сих пор нет подсказки, ниже приведен обходной путь (игнорируя ошибки?)

$products = array();
foreach ($request->get('quantity') as $key => $var) {
    if ($var > 0) {
        $product = Product::with(['country'])->where('mall_' . $this->mall_id, '=', 1)
                    ->find($key);

        foreach ($product->country as $c) {
            if ($c->country_id == $me->country_id && !isset($products[$product->id])) {
                //Do something here...
            }
        }
    }
}

введите описание изображения здесь

введите описание изображения здесь

введите описание изображения здесь

введите описание изображения здесь


person user259752    schedule 29.09.2017    source источник
comment
Вы пытались присоединиться к таблицам вместо проверки существования?   -  person Syed Talha Hai    schedule 29.09.2017
comment
еще не пробовал присоединиться, но хотел бы знать, что случилось с этим проверочным запросом на существование, выглядит нормально, но не работает, действительно странно / ошибка   -  person user259752    schedule 29.09.2017
comment
почему вы используете find() после построения запроса?   -  person Oluwatobi Samuel Omisakin    schedule 29.09.2017
comment
я использую find, потому что хочу найти точный продукт, и я использую whereHas вместе, потому что я хочу, чтобы запрос также выполнял ПРОВЕРКУ, гарантируя, что ни один продукт не будет заказан из другой страны, я думаю, что этот способ не позволит пользователю проверить элемент, редактирующий идентификатор продукта в форма заказа   -  person user259752    schedule 29.09.2017
comment
привет, я думаю, вы получили бы большую пользу от методов сбора данных laravel (laravel.com/ docs/5.4/коллекции#доступные-методы). В частности, методы «карты» и «фильтра».   -  person ochhii    schedule 03.10.2017
comment
я знаю, что есть много альтернативных способов, я также предоставил 1, мне просто любопытно, почему произошла ошибка и в чем причина, чтобы улучшить   -  person user259752    schedule 04.10.2017
comment
Я пробовал, и это просто прекрасно   -  person Basheer Kharoti    schedule 09.10.2017


Ответы (6)


я создал таблицы, упомянутые выше (указав точно такие же отношения, имена таблиц, имена моделей) и попробовал ваш код (указав жестко закодированные значения)

public function try1(){
    $me = 109;
    $key = 3;
    $product = Product::where('mall_3' , '=', 1)
        ->whereHas('country', function ($i) use ($me) {
            return $i->where('country_id', $me);
        })

        ->find($key);

    return $product;
}

public function try2(){
    $me = 109;
    $key = 6;
    $product = Product::where('mall_3' , '=', 1)
        ->whereHas('country', function ($i) use ($me) {
            return $i->where('country_id', $me);
        })

        ->find($key);

    return $product;
}

но получили отличные результаты

 {"id":3,"mall_1":1,"mall_2":1,"mall_3":1}

а также

{"id":6,"mall_1":1,"mall_2":1,"mall_3":1}

пожалуйста, проверьте, все ли в порядке с вашей базой данных, проверьте, все ли первичные и внешние ключи созданы как «целые числа». И проверьте "сопоставление" БД, а также таблиц.

person ajith mohan    schedule 03.10.2017
comment
тогда это странно, я просто перепроверил, подтвердил, что product_country.product_id является UNSIGNED INTEGER (10), я также проверил, что и product_country, и product TABLE имеют одинаковую сортировку utf8_unicode_ci - person user259752; 04.10.2017

Это не похоже на Laravel (поскольку вы по-прежнему не получаете результатов при выполнении запроса напрямую с MyAdmin).

select * from `product`
where true
-- and `mall_3` = '1'
and exists (
    select * from `product_country`
    where true
    and `product_country`.`product_id` = `product`.`id`
    and `country_id` = '109'
)
and `product`.`id` = '3'
and `product`.`deleted_at` is null
limit 1

Запустите запрос еще раз, комментируя каждое условие where одно за другим (я добавил первое условие true, чтобы легко закомментировать все строки «and ...»), чтобы увидеть, где начинается проблема.

(Кстати, я пытался создать обе таблицы, и оба запроса возвращают правильные результаты.)

person alepeino    schedule 04.10.2017
comment
после такой проверки я обнаружил, что deleted_at не равно NULL для product.id = 3, какая нубская ошибка, спасибо - person user259752; 05.10.2017
comment
@ user259752 Но как это возможно? На вашем скриншоте deleted_at равно NULL. - person Paul Spiegel; 07.10.2017
comment
@PaulSpiegel, ты прав, я не проверял свой скриншот в прошлый раз, но теперь моя база данных удалена_на самом деле нулевая - person user259752; 08.10.2017
comment
@user259752 user259752, так что теперь они оба нулевые, но идентификатор 3 по-прежнему не находит результатов, а идентификатор 6 находит? - person alepeino; 08.10.2017
comment
я пробовал экспортировать и импортировать одни и те же данные на свой тестовый сервер, он нормальный / работает правильно, я попытался установить xampp на свой компьютер с Windows и импортировать те же данные, он тоже работает, теперь похоже, что только мой wampserver 64bit mysql5.7.14 не работает - person user259752; 09.10.2017

попробуйте это, надеюсь, это поможет вам,

 $products = array();
    foreach ($request->get('quantity') as $key => $var) {
        if ($var > 0) {
            $product = Product::where('mall_' . $this->mall_id, '=', 1)
                        ->leftjoin('product_country','product_country.product_id','=','product.id')->get();
            $products[$product->id] = ['product_id'=>$product->id,'country_id'=>$product->country_id];              
        }
    }
person Hamelraj    schedule 05.10.2017

Я думаю, вам следует изменить концепцию отношений в модели продукта с hasMany на ownToMany.
Также обновите параметры, определив модель страны в качестве первого аргумента, имя промежуточной таблицы в качестве второго аргумента, а затем внешний ключ и первичный ключ в качестве третьего и четвертого. аргументы. belongsToMany('App\Models\Country', 'product_country','product_id', 'country_id')

Модель продукта

public function country() {
    return $this->belongsToMany('App\Models\Country', 'product_country','product_id', 'country_id');
}

Потому что каждая страна может принадлежать многим продуктам, а каждый продукт может принадлежать многим странам.

person Vijay Wilson    schedule 05.10.2017

Перво-наперво:

Если вы используете eloquent (метод поиска), вы можете сделать что-то вроде:

Product::find($id);

и он возвращает модель продукта, в которой предоставленный вами идентификатор равен первичному ключу. При этом нет необходимости использовать whereHas(), так как это не будет иметь никакого эффекта. Вместо find() вы можете попробовать, например, get() или first(), в зависимости от того, что вы ищете.

Если вы хотите распечатать свой запрос, вы можете закончить его ->toSql();, и он напечатает запрос в виде строки (очень помогает!).

Я не обращал особого внимания на цель, но я уверен, что если вы используете

dd(Product::where('mall_' . $this->mall_id, '=', 1)
->whereHas('country', function ($i) use ($me) {
    return $i->where('country_id', $me->country_id);
})
->toSql());

Вы сможете сравнить то, что вы делаете (поскольку вы знаете, каким должен быть правильный результат или запрос), и сможете понять это.

В конце концов, нам нужно тренироваться, чтобы исследовать наш разум!

person abr    schedule 29.09.2017
comment
я думаю, что это ошибка mysql вместо laravel, я использую whereHas, потому что система показывает продукт пользователю только в том случае, если пользователь находится в стране, подумайте, где также будет выполнять ВАЛИДАЦИЯ, поэтому не будет заказа за пределами страны, вы можете видеть 2 запроса, которые я пишу, делаю то же самое, но один получил результат, а другой - нет, и глядя на изображение, которое я загрузил, уже доказательство того, что оба 2 запроса должны иметь результат - person user259752; 29.09.2017
comment
Я использовал whereHas раньше, и у меня не было никаких проблем, но я постараюсь реализовать то, что написал OP, когда вернусь домой, если у меня будет время, и, надеюсь, я смогу дать некоторые обновления по этому вопросу. У меня есть небольшой опыт работы с laravel (около 4 месяцев), но когда дело доходит до Eloquent, я иногда забываю, какие результаты они дают. - person abr; 29.09.2017

Я знаю, что эта ветка немного устарела, но у моей команды была очень похожая проблема с Laravel и whereHas (MySQL EXISTS) в MySQL 5.7.18.

Как только мы обновили MySQL, тот же запрос начал возвращаться точно так, как и ожидалось. Я еще не понял, было ли это ошибкой с 5.7.18, но я подозреваю, что это может быть.

person Matt    schedule 31.01.2018