Value Displays Blank when I tried to edit in Laravel - laravel

I want to edit in laravel
In my controller I have this
public function edit(Book $book)
{
return view ('admin.book.edit')->with('book', $book)->with('authors', Author::all())->with('categories', Category::all());
}
In my index view for all books, I have this
<tbody>
#foreach($books as $book)
...
<td> {{ $book -> name }} </td>
<td>
<a href="{{ route('admin.book.edit',$book->id) }}">
<button class="btn btn-success">Edit</button>
</a>
</td>
...
My Edit view is like this
<form action="#" method="POST" enctype="multipart/form-data">
#csrf
<div class="form-group">
<label for="name">Book Name</label>
<input type="text" class="form-control" name="name" id="name" value="{{ $book->name }}" >
</div>
<div class="form-group">
<label for="about">About the Book </label>
<textarea name="about" id="about" cols="5" rows="5" class="form-control">{{ $book->about }}</textarea>
</div>
In my web.php
Route::get('/admin/book/edit', 'BooksController#edit')->name('admin.book.edit');
My table schema
Schema::create('books', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->text('about');
...
});
I was thinking this value="{{ $book->name }}" will return the value but it returned blank. Probably I am doing something wrong here.

Hi you don't define in your route Model bindings:
Change it to, so Laravel knows that the ID you pass in route should return Book Model. That you use in your edit function edit(Book $book)
Route::get('/admin/book/edit/{book}', 'BooksController#edit')->name('admin.book.edit');
Also take a look into Resource Controllers:
Route::resource('books', 'BooksController');
This will generate all routes you need view/edit/update/delete Check your routes bu running php artisan route:list
Read Docs for more info

They was an error in my route, so I change to this
Route::get('/admin/book/edit/{book}', 'BooksController#edit')->name('admin.book.edit');

Related

Field 'vaccine_id' doesn't have a default value

why i'm getting this error?
First view
` #foreach ($appointments as $appointment)
<div class="card m-2 p-2">
<div class="card-body">
<h6 class="card-title">Vaccine: {{ $appointment->vaccine }}</h6>
<div class="mb-6" style="float: right; margin-top: 10px">
<form action="/appointment/{{ $appointment->id }}">
<input type="submit" class="bg-black text-white rounded py-2 px-4 hover:bg-black"
value="Schedule Now">
</form>
</div>
</div>
</div>
#endforeach`
First view Controller
` public function showAppointment()
{
return view('appointmentForm');
}`
Second View
` <form action="/appointment/create" enctype="multipart/form-data" method="POST">
#csrf
<div class="name">
<label for="name" class="form-label">Name:</label>
<input type="text" name="name" id="name" placeholder="Enter name">
</div>
</form>`
Route
`Route::get('/appointment/{id}', [AppointmentController::class, 'showAppointment'])->middleware('guest');`
` public function showAppointment()
{
return view('appointmentForm');
}`
i have two migration file
` Schema::create('appointments', function (Blueprint $table) {
$table->id();
$table->string('vaccine');
$table->timestamps();
});`
` Schema::create('usersappointments', function (Blueprint $table) {
$table->id();
$table->foreignId('vaccine_id')->constrained('appointments')->onUpdate('cascade')->onDelete('cascade');
$table->string('name');
$table->timestamps();
});`
Model
` protected $fillable = [
'vaccine_id', 'name'
];`
Controller
` public function createAppointment(Request $request)
{
$data = $request->validate([
'name' => 'required'
]);
usersappointments::create($data);
return redirect('/');
}`
This is how it works; the user select vaccines he want then he will redirect to a page which he will input his name but i'm getting this error
You need to set input vaccine_id in second view in order to send data to controller
<form action="/appointment/create" enctype="multipart/form-data" method="POST">
#csrf
<div class="name">
<label for="name" class="form-label">Name:</label>
<input type="hidden" name="vaccine_id" value="" /> // here get the vaccine_id in value which is selected in first view
<input type="text" name="name" id="name" placeholder="Enter name">
</div>
</form>

Function is not returning true value

I have a Model that takes care of followers:
Schema::create('follows', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('user_id');
$table->unsignedBigInteger('follower_id');
$table->dateTime('followed_date')->nullable();
$table->dateTime('unfollowed_date')->nullable();
$table->timestamps();
$table->unique(['user_id', 'follower_id']);
});
The issue is I have this piece of code in the User.php model that is not returning true when I follow the user:
public function following()
{
return $this->hasMany(Follow::class);
}
public function isFollowing($profileUser)
{
return $this->following()->where(['user_id' => $profileUser, 'follower_id' => auth()->id()])->exists();
}
Here is the code that I have in the view:
#if(auth()->user()->isFollowing($profileUser->id) == FALSE)
<li>
<form action="/follow/{{ $profileUser->name }}" method="POST">
{{ csrf_field() }}
<input type="hidden" name="user_id" value="{{ $profileUser->id }}">
<input type="hidden" name="follower_id" value="{{ auth()->user()->id }}">
<button type="submit">Follow</button>
</form>
</li>
#else
<li>
<form action="/follow/{{ $profileUser->name }}" method="POST">
{{ csrf_field() }}
<input type="hidden" name="user_id" value="{{ $profileUser->id }}">
<input type="hidden" name="follower_id" value="{{ auth()->user()->id }}">
<button type="submit">Unfollow</button>
</form>
</li>
#endif
Does anyone know why my code is not working? Thanks in advance!
So the issue was I didn't even know the structure of my Model,
I confused the user_id column with the $request->follower_id,
I'm going to make it following_id to make it more clear what the relationship is...
A user will be "following" another user... simple!

PUT/POST in Laravel

I'm brand new to Laravel and am working my way through the [Laravel 6 from Scratch][1] course over at Laracasts. The course is free but I can't afford a Laracasts membership so I can't ask questions there.
I've finished Section 6 of the course, Controller Techniques, and am having unexpected problems trying to extend the work we've done so far to add a few new features. The course has students build pages that let a user show a list of articles, look at an individual article, create and save a new article, and update and save an existing article. The course work envisioned a very simple article containing just an ID (auto-incremented in the database and not visible to the web user), a title, an excerpt and a body and I got all of the features working for that, including updating an existing article and saving it.
The update form sets method to POST but then uses a #METHOD('PUT') directive to tell the browser that it is actually supposed to do a PUT. This worked perfectly in the original code. However, now that I've added two more fields to the form, when I click Submit after editing an existing record, the save fails with this message:
Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException
The PUT method is not supported for this route. Supported methods: GET, HEAD, POST.
http://localhost:8000/articles
I don't understand why adding two fields to the form would cause this to break. Can someone enlighten me? I added the two new fields/columns to the migration and ran migrate:rollback and migrate. I've also added the new fields/columns to the fillable attribute and added validations for them in the ArticlesController.
Here is my routing:
Route::get('/articles', 'ArticlesController#index');
Route::post('/articles', 'ArticlesController#store');
Route::get('/articles/create', 'ArticlesController#create');
Route::get('/articles/{article}', 'ArticlesController#show');
Route::get('/articles/{article}/edit', 'ArticlesController#edit');
Route::put('/articles/{article}', 'ArticlesController#update');
//Route::delete('/articles/{article}', ArticlesController#destroy');
This is my ArticlesController:
<?php
namespace App\Http\Controllers;
use App\Article;
use Illuminate\Http\Request;
class ArticlesController extends Controller
{
public function index()
{
$articles = Article::latest()->get();
return view ('articles.index', ['articles' => $articles]);
}
public function show(Article $article)
{
return view('articles.show', ['article' => $article]);
}
public function create()
{
return view('articles.create');
}
public function store()
{
//Stores a NEW article
Article::create($this->validateArticle());
return redirect('/articles');
}
public function edit(Article $article)
{
return view('articles.edit', ['article' => $article]);
}
public function update(Article $article)
{
//Updates an EXISTING article
$article->update($this->validateArticle());
return redirect('/articles/', $article->id);
}
public function validateArticle()
{
return request()->validate([
'title' => ['required', 'min:5', 'max:20'],
'author' => ['required', 'min:5', 'max:30'],
'photopath' => ['required', 'min:10', 'max:100'],
'excerpt' => ['required', 'min:10', 'max:50'],
'body' => ['required', 'min:50', 'max:500']
]);
}
public function destroy(Article $article)
{
//Display existing record with "Are you sure you want to delete this? Delete|Cancel" option
//If user chooses Delete, delete the record
//If user chooses Cancel, return to the list of articles
}
}
Here's my edit form, edit.blade.php:
#extends('layout')
#section('content')
<div id="wrapper">
<div id="page" class="container">
<h1>Update Article</h1>
<form method="POST" action="/articles">
#csrf
#method('PUT')
<div class="form-group">
<label class="label" for="title">Title</label>
<div class="control">
<input class="form-control #error('title') errorborder #enderror" type="text" name="title" id="title" value="{{ $article->title }}">
#error('title')
<p class="errortext">{{ $errors->first('title') }}</p>
#enderror
</div>
</div>
<div class="form-group">
<label class="label" for="author">Author</label>
<div class="control">
<input class="form-control #error('author') errorborder #enderror" type="text" name="author" id="author" value="{{ $article->author }}">
#error('title')
<p class="errortext">{{ $errors->first('author') }}</p>
#enderror
</div>
</div>
<div class="form-group">
<label class="label" for="photopath">Path to Photo</label>
<div class="control">
<input class="form-control #error('photopath') errorborder #enderror" type="text" name="photopath" id="photopath" value="{{ $article->photopath }}">
#error('title')
<p class="errortext">{{ $errors->first('photopath') }}</p>
#enderror
</div>
</div>
<div class="form-group">
<label class="label" for="excerpt">Excerpt</label>
<div class="control">
<textarea class="form-control #error('excerpt') errorborder #enderror" name="excerpt" id="excerpt">{{ $article->excerpt }}</textarea>
#error('excerpt')
<p class="errortext">{{ $errors->first('excerpt') }}</p>
#enderror
</div>
</div>
<div class="form-group">
<label class="label" for="body">Body</label>
<div class="control">
<textarea class="form-control #error('body') errorborder #enderror" name="body" id="body">{{ $article->body }}</textarea>
#error('body')
<p class="errortext">{{ $errors->first('body') }}</p>
#enderror
</div>
</div>
<div class="control">
<button class="btn btn-primary" type="submit">Submit</button>
</div>
</form>
</div>
</div>
#endsection
Is there anything else you need to see?
[1]: https://laracasts.com/series/laravel-6-from-scratch/episodes/33?autoplay=true
Your Laravel route is:
Route::put('/articles/{article}', 'ArticlesController#update');
So your form action url should match that uri:
<form action="{{ url('/articles/'.$article->id) }}">
where the {article} parameter is the record id (you can read more about in the docs here).
Then in your controller update() method, you have:
return redirect('/articles/', $article->id);
which means redirect to /articles with status code $article->id (you can read more about in the docs here). I think you are trying to redirect to the show route, which is:
Route::get('/articles/{article}', 'ArticlesController#show');
So change the , (comma) to a . (dot) to concatenate the article id with the uri:
return redirect('/articles/' . $article->id);
The route in the form for /articles, However your route for updating should be /articles/{article}
Try this:
<form method="POST" action="/articles/{{ $article->id }}">

Laravel 5.7 using same url action for insert and update with #yield in blade template

I am using laravel 5.7 and I am using one form for inserting and updating. In form action I want to use #yield() for laravel route to get the id for updation. Every thing is fine but I can't use #yield() method. Here is my code, problem is only in action of the form.
<form class="form-horizontal" action="{{ url('/todo/#yield('editId')') }}" method="post">
{{csrf_field()}}
#section('editMethod')
#show
<fieldset>
<div class="form-group">
<div class="col-lg-10">
<input type="text" name="title" placeholder="Title" value="#yield('editTitle')" class="form-control">
</div>
</div>
<div class="form-group">
<div class="col-lg-10">
<textarea class="form-control" placeholder="Body" name="body" rows="5" id="textarea">#yield('editBody')</textarea>
<br>
<button type="submit" class="btn btn-success">Submit</button>
</div>
</div>
</fieldset>
</form>
I have also checked with single and double quotes.
action="/todo/#yield('editid')"
When I use simple this method then after submitting it redirects me to localhost and with an error page not found. In laravel 5.4 it works. but not in laravel 5.7. Any help would be appreciated Thanks
Here is my edit.blade.php from where I am using the #section and #yield
#extends('Todo.create')
#section('editId',$item->id)
#section('editTitle',$item->title)
#section('editBody',$item->body)
#section('editMethod')
{{ method_field("PUT") }}
#endsection
Controller store edit and update methods are
public function store(Request $request)
{
$todo = new todo;
$this->validate($request,[
'body'=>'required',
'title'=>'required|unique:todos',
]);
$todo->body = $request->body;
$todo->title = $request->title;
$todo->save();
return redirect("todo");
}
public function edit($id)
{
$item = todo::find($id);
return view("Todo.edit",compact('item'));
}
public function update(Request $request, $id)
{
$todo = todo::find($id);
$this->validate($request,[
'body'=>'required',
'title'=>'required',
]);
$todo->body = $request->body;
$todo->title = $request->title;
$todo->save();
return redirect("/todo");
}
To answer the OP actual question you would need to do
#section('editId', "/$item->id") or #section('editId', '/'.$item->id')
{{ url('/todo') }}#yeild('editId')
But much better to do
{{ url('/todo/'.(isset($item) ? $item->id : '')) }}
Or for PHP >= 7
{{ url('/todo/'.($item->id ?? '')) }}
As apokryfos already mentioned - #yield is thought to make reusing your templates easier.
If you simply want to determine (for example) which action should be called afterwards you should better do something like that:
#extends('Todo.create')
<form class="form-horizontal" action="/todo/{{ isset($item) ? $item->id : '' }}" method="post">
#if( ! isset($item))
{{ method_field("PUT") }}
#else
{{ method_field("PATCH") }}
{{csrf_field()}}
<fieldset>
<div class="form-group">
<div class="col-lg-10">
<input type="text" name="title" placeholder="Title" value="{{ isset($item) ? $item->title : '' }}" class="form-control">
</div>
</div>
<div class="form-group">
<div class="col-lg-10">
<textarea class="form-control" placeholder="Body" name="body" rows="5" id="textarea">{{ isset($item) ? $item->body : '' }}</textarea>
<br>
<button type="submit" class="btn btn-success">Submit</button>
</div>
</div>
</fieldset>
</form>
Also as I remember the method field should always come first to make sure it's recognized correctly. Additionally you shouldn't need url() to generate the url I think.
No need for a second blade. Simply inject the variables directly into the template and make sure they are set before you access them. I didn't try it but I'd think that it should work.

Laravel Cannot retrieve a specific record from a form

I am outputting a list from a database table 'books' like this:
function edit()
{
$books = Book::all();
return view('layouts/editbooks', ['books' => $books]);
}
And displaying them like this:
#extends('layouts.master')
#section('title')
#section('content')
<h1>Edit Book</h1>
<form action="{{url('editbook')}}" method="GET">
{{ csrf_field() }}
#foreach ($books as $book)
<div>
<label>{{$book->title}}</label>
<input type='radio' value='{{$book->id}}' name='books[]'/>
</div>
#endforeach
<input type="submit" class="btn btn-warning form-control" value="Edit">
</form>
#endsection
I then want user to choose which record they want to edit by selecting a radio button, and upon clicking a submit button, redirect user to a new page with details of a book.
Therefore I am trying to get a book id from radio button and then if id matches, display everything from that record:
function editing(Request $request)
{
$edit = $request->books;
return view('layouts/editing', ['edit' => $edit]);
}
function updateEdit()
{
$books = DB::table('books')->where('id', $edit)->first();
}
And that is displayed in a view:
#extends('layouts.master')
#section('title')
#section('content')
<h1>Delete Book</h1>
<form action="{{url('removebook')}}" method="POST">
{{ csrf_field() }}
<div>
<input name="name" type="textbox" value="{{ old('name', $edit['name']) }}"/>
</div>
<input type="submit" name="submitBtn" value="Delete Book">
</form>
#endsection
However I get an error message saying:
Undefined index: name (View: C:\xampp\htdocs\laraveladvweb\resources\views\layouts\editing.blade.php)
What is causing the issue?
Isn't $edit just the id of the book?
try this
function editing(Request $request)
{
$edit = $request->books;
$book = DB::table('books')->where('id', $edit)->first();
return view('layouts/editing', ['edit' => $book]);
}
#extends('layouts.master')
#section('title')
#section('content')
<h1>Delete Book</h1>
<form action="{{url('removebook')}}" method="POST">
{{ csrf_field() }}
<div>
<input name="name" type="textbox" value="{{ old('name', $edit['name']) }}"/>
</div>
<input type="submit" name="submitBtn" value="Delete Book">
</form>
#endsection

Resources