Проблема с коллекцией Laravel 5: где не равно

В настоящее время я работаю над модальным, где пользователь может вставить файл excel. Задача системы — загрузить и/или добавить новую запись в базу данных, если записи новые или идентичны тем, что уже есть в базе. НО ему также нужна функция удаления для избавления от тех записей, где столбец slug не идентичен столбцу имени.

На данный момент я использую Laravel 5.3, и это мой контроллер, как сейчас:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Product;
use App\Http\Requests;
use Illuminate\Support\Facades\DB;
use Input;
use Maatwebsite\Excel\Facades\Excel;

class ProductsController extends Controller {

public function importExcel(Request $request) {
    if (Input::hasFile('productFile')) {
        $path = Input::file('productFile')->getRealPath();
        $checkbox = Input::get('productCheckbox');
        $data = Excel::load($path, function($reader) {
        })->get();

        if (!empty($data) && $data->count()) {
            foreach ($data as $key => $value) {
                $product = Product::all()->where('slug', $value->slug)->first();
                $product_false = Product::all()->where('slug', '!=' , 'name')->get();

                if ($product_false !== null){
                    //delete row if slug does not matches name
                    dd($product_false);
                }

Приведенный выше dd возвращает все продукты, поэтому запрос коллекции работает неправильно (см. ниже необработанный SQL, который я пытаюсь запустить в этой коллекции)

                if ($product !== null) {
                    //update row if exist
                    $product->name = $value->name;
                    $product->description = $value->description;
                    $product->price = $value->price;
                    $product->save();
                } else {
                    //add new row if not exist
                    $product = new Product;
                    $product->slug = $value->slug;
                    $product->name = $value->name;
                    $product->description = $value->description;
                    $product->price = $value->price;
                    $product->save();
                }

            }
            header("Location: /products");
        }
    }
}

}

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

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{

/**
 * The attributes that are mass assignable.
 *
 * @var array
 */
protected $fillable = [
    'slug', 'name', 'description', 'price',
];
}

Вот необработанный SQL PHPMyAdmin (который работает), который я в основном ищу для использования в коллекции:

SELECT * FROM `products` WHERE `slug` != `name`

Я надеюсь, что кто-то может помочь мне из этой ямы. Я бороздил просторы Интернета около 12 часов, чтобы сделать это.

~ цудж


person Justin Boxem    schedule 16.09.2016    source источник
comment
вместо != один раз попробуйте с <>   -  person Anant Kumar Singh    schedule 16.09.2016
comment
Замена '!=' на '‹›' привела к следующему результату: prntscr.com/cili89   -  person Justin Boxem    schedule 16.09.2016
comment
Разве это не неправильно $product_false = Product::all()->where('slug', '!=' , 'name')->get(); ? Не должно быть $product_false = Product::all()->where('slug', '!=' , $value->slug)->get();   -  person KuKeC    schedule 16.09.2016
comment
Эй, спасибо, но это не сработало. Вместо этого я получил: prntscr.com/cimdm8   -  person Justin Boxem    schedule 16.09.2016


Ответы (4)


Коллекции, красноречивый и построитель запросов — это не одно и то же. Коллекция предоставляет набор методов для работы с массивами, а не с базой данных или моделью.

В контексте коллекции whereNot() недоступен.

но та же функция может быть достигнута через whereNotIn('key', [value])

collect([
    [
      'name' => 'foo',
      'rank' => 2
    ],[
      'name' => 'bar',
      'rank' => 3
    ],[
      'name' => 'foobar',
      'rank' => 4
    ],
 ])->whereNotIn('rank', [4])

то же, что where rank not in (4)

person f_i    schedule 14.08.2019

Изменять

$product = Product::all()->where('slug', $value->slug)->first();
$product_false = Product::all()->where('slug', '!=' , 'name')->get();

В

$product = Product::where('slug', $value->slug)->first();
$product_false = Product::where('slug', '!=' , 'name')->get();
person Leguam    schedule 16.09.2016
comment
Я пробовал это раньше. Это все записи; включая те, где slug и name фактически совпадают: prntscr.com/cilj0n - person Justin Boxem; 16.09.2016
comment
Вероятно, это связано с тем, что третий аргумент анализируется как строка, попробуйте использовать products.slug и products.name вместо только имен столбцов. Вы также можете использовать, возможно, лучший способ: $products_false = Product::whereRaw('slug != name'); - person Jan Willem; 16.09.2016
comment
product.slug / product.name приводит к следующему результату: prntscr.com/cily1l ur где исходное предложение приводит к следующему результату: prntscr.com/cilyjg для дальнейшего использования, мне просто нужно запустить тест на модели продукта и получить записи, где ' столбец slug НЕ равен столбцу «имя». - person Justin Boxem; 16.09.2016
comment
Это потому, что при использовании whereRaw вам нужно добавить к нему ->get(), так как теперь возвращается только построитель запросов. - person Jan Willem; 16.09.2016

Попробуй это

$product = Product::where('slug', $value->slug)->first();
$product_false = Product::whereRaw('slug != name')->get();

Простой where не будет работать, так как он сравнивает products.slug с "name"(строка).

person linuxartisan    schedule 16.09.2016

Мне удалось решить ее.

$data = Excel::load($path, function($reader) {

            $importedSlugs = $data->select(array('slug'))->toArray();
                    //collection of imported slugs
                    $collectionOfImportedSlugs = collect($importedSlugs)->flatten()->all();

                    //get all product slugs
                    $productSlugs = Product::all()->pluck('slug');

                    //get all different slugs!
                    $diffSlugsArray = $productSlugs->diff($collectionOfImportedSlugs)->all();
                    //dd($diffSlugsArray);

                    foreach ($diffSlugsArray as $diffSlug) {
                        $product_false = Product::all()->where('slug',     $diffSlug)->first();

                        echo $product_false->slug . 'has been deleted!';

                        $product_false->delete();
                    }
        })->get();
person Justin Boxem    schedule 16.09.2016