#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()
вместо написания каждого маршрута по отдельности, это снижает вероятность ошибки, как та, которую я сделал.
Еще раз спасибо всем.