Laravel: свойство [имя] не существует в этом экземпляре коллекции при попытке заполнить поле в режиме редактирования

#php #laravel

#php #laravel

Вопрос:

Я только начинаю изучать Laravel и, следуя серии Laracast «Laravel с нуля», я дошел до создания страницы редактирования, на которой мне нужно получить идентификатор продукта и заполнить входные данные существующими данными, но, следуя инструкциям в видео, я продолжаю получать ошибку

«Свойство [имя] не существует в этом экземпляре коллекции».

ProductController.php

 public function edit(Product $id)
{
    $product = Product::find($id);

    return view('admin.product.edit', compact('product'));
}
 

edit.blade.php

 <div class="container">
<div class="row justify-content-center">
    <div class="col-md-8">
        <div class="card">
            <div class="card-header">Edit product</div>

            <div class="card-body">
                <form action="/product" method="post">
                    @csrf
                    <input type="text" name="name" id="name" placeholder="Name" value="{{$product->name}}">
                    <br>
                    <textarea name="description" id="descriptopn" cols="30" rows="10" placeholder="Description">{{$product->description}}</textarea>
                    <br>
                    <input type="number" name="price" id="price" min="0.1" step="0.01" placeholder="Price" value="{{$product->price}}">
                    <br>
                    <input type="number" name="stock" id="stock" min="1" step="1" placeholder="Stock" value="{{$product->stock}}">
                    <br>
                    <button type="submit">Save</button>
                </form>
            </div>
        </div>
    </div>
</div>
 

Если это поможет, я в настоящее время использую Laravel версии 8.22.1 (PHP версии 8.0.0), и я полагаю, что во время записи серии Laracast использовал Laravel версии 6.

Редактировать: добавление структуры таблицы.

Файл миграции:

create_products_table.php

 public function up()
{
    Schema::create('products', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->text('description')->nullable();
        $table->float('price');
        $table->integer('stock');
        $table->timestamps();
    });
}
 

Редактирование # 2: добавление модели продукта

Product.php

 class Product extends Model
{
    use HasFactory;
}
 

web.php

 Route::get('/', function () {
return view('welcome');
});

Auth::routes();

Route::get('/home', [AppHttpControllersHomeController::class, 'index'])->name('home');

//Admin routes
Route::get('/product', [ProductController::class, 'index']);
Route::post('product', [ProductController::class, 'store']);
Route::get('/product/create', [ProductController::class, 'create']);
//Route::get('/product/{article}', [ProductController::class, 'show']);
Route::get('/product/{article}/edit', [ProductController::class, 'edit']);
Route::put('/product/{product}', [ProductController::class, 'update']);
 

Спасибо всем за ваши ответы, я помню, что использовал тот же стиль логики в Laravel 6, и все работало, но теперь у меня возникли проблемы с Laravel 8, если избавиться от сообщения об ошибке с помощью предложений @ByWaleed и @vozaldi, тогда входные данные в edit.blade.php не заселяйтесь с помощьюнеобходимые данные, консоль Firefox не показывает никаких ошибок, а при использовании dd() отображается следующим образом

dd($id):

 AppModelsProduct {#303 ▼
#connection: null
#table: null
#primaryKey: "id"
#keyType: "int"
 incrementing: true
#with: []
#withCount: []
#perPage: 15
 exists: false
 wasRecentlyCreated: false
#attributes: []
#original: []
#changes: []
#casts: []
#classCastCache: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
 timestamps: true
#hidden: []
#visible: []
#fillable: []
#guarded: array:1 [▼
   0 => "*"
  ]
}
 

dd($product)

 IlluminateDatabaseEloquentCollection {#1184 ▼
    #items: []
}
 

Комментарии:

1. Можете ли вы показать мне свою структуру таблицы продуктов?

2. Не думайте, что вам нужна первая строка в функции, потому что ваш параметр функции найдет продукт с заданным идентификатором, и вы сможете получить доступ к продукту в переменной $id . Поэтому попробуйте передать $id в представление.

3. @ByWaleed в качестве вашего предложения я закомментировал первую строку и передал $id в представление, это не выдает мне ошибку, о которой я упоминал выше, но она не заполняет входные данные данными, связанными с указанным идентификатором. Конечно, a внес необходимые изменения в edit.blade.php и файлы ProductController.

4. Используйте findOrFail вместо этого.

5. @SMIftakhairul спасибо за ваше предложение, но при использовании findOrFail ошибка сохраняется.

Ответ №1:

Добро пожаловать в сообщество Laravel.

Здесь я вижу в вашем контроллере public function edit (Product $id) , где $id уже есть модель.

Поэтому вместо этого вы должны сделать так

 public function edit(Product $product)
{
    return view('admin.product.edit', compact('product'));
}
 

или в более старом Laravel выполняется следующим образом

 public function edit(Request $request, $id)
{
    $product = Product::findOrFail($id);

    return view('admin.product.edit', compact('product'));
}
 

Вы можете отладить свою функцию codes dump() или dd() . Например:

 public function edit(Product $id)
{
    dd($id); // debug $id and exit

    ...rest of code
}
 

Комментарии:

1. Спасибо за ваш ответ, но, несмотря на то, что я избавляюсь от ввода сообщения об ошибке в edit.blade.php не заполняйтесь данными о продукте.

2. Есть ли какое-либо сообщение об ошибке? или вы выполнили какую-либо отладку?

Ответ №2:

Спасибо всем за ваше время

Все ваши ответы очень полезны, но, оказывается, я просто допустил опечатку.

В маршруте редактирования Route::get('/product/{article}/edit', [ProductController::class, 'edit']); я написал {article} вместо {product} (как для модели, так и для контроллера с именем Product), как указано @ByWaleed . После внесения этого исправления все работает правильно.

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

Еще раз спасибо всем.