Delete data from the database with Laravel 5.4 - php

I am sort of new to the Laravel framework and I am building just a simple blog. I can create a blog, show a blog and show a overview of all blogs. Now I would like to delete a blog. So, I have created a delete button in my view with a route link which will pass also the id of the article. Then, in my routes file I specify a delete request and a controller method. In the method I find the id and try to delete the row with the id I specified in the route/view.
This doesn't work. Instead of activate the destroy/delete method it shows the article instead of deleting it and activates the show method instead of the delete method. Can somebody help me out, What do I wrong?
View.blade.php
<a href="{{route('nieuws.destroy', ['id' => $blog->id])}}" onclick="return confirm('Weet je dit zeker?')">
<i class="fa fa-trash"></i>
</a>
Route
Route::group(['middleware' => 'auth'], function () {
Route::get('/aanvragen', 'aanvragenController#index')->name('aanvragen.index');
Route::get('/logout' , 'Auth\LoginController#logout')->name('logout');
Route::get('/nieuws/toevoegen', 'blogController#create')->name('blogs.add');
Route::post('/nieuws/store', 'blogController#store')->name('nieuws.store');
Route::delete('/nieuws/{id}', 'blogController#destroy')->name('nieuws.destroy');
});
Route::get('/nieuws', 'blogController#index')->name('blogs.index');
Route::get('/nieuws/{blog}', 'blogController#show')->name('blogs.show');
Controller methods
Delete/Destroy
public function destroy($id) {
$blog = Blog::find($id);
$blog->delete();
return redirect('/nieuws');
}
Show
public function show(Blog $blog) {
dd('show');
return view('blogs.show', compact('blog'));
}

A delete() route requires you to POST your data.
HTML forms only supports GET and POST, other methods like DELETE, PUT, etc are not supported, that's why Laravel uses the _method to spoof methods which are not supported by HTML forms.
You do not want use GET in these cases, since someone can send a user the url (http://yoursite.com/blog/delete/1) in an IM or via email. The user clicks and the blog is gone.
Define your route as it would be when using resource controllers, so:
Route::delete('/nieuws/{id}', 'blogController#destroy')->name('nieuws.destroy');
And either use a form with the delete method:
// apply some inline form styles
<form method="POST" action="{{ route('nieuws.destroy', [$blog->id]) }}">
{{ csrf_field() }}
{{ method_field('DELETE') }}
<button type="submit">Delete</button>
</form>
Or do some javascript magic as the link SR_ posted in his comment on your OP.
One more thing, add some sort of validation in your destroy action. Right now when you provide a non-existing id or something else, you will get a 500 error, instead you want to have a 404.
public function destroy($id)
{
$blog = Blog::findOrFail($id);
$blog->delete();
return redirect('/nieuws');
}

I think you need to update your destroy function like:
public function destroy($id) {
$blog = DB::table('blog')->where('id',$id)->delete();
return redirect('/nieuws');
}
And update your view code like:
<a href="{{route('nieuws.destroy', [$blog->id])}}" onclick="return confirm('Weet je dit zeker?')">
<i class="fa fa-trash"></i>
</a>
Hope this work for you!

I'm also new to Laravel but I made it work through this way:
(I use 'Article' as the model's name and the resource "method" in the route stands for a bunch of useful routes including the route you wrote)
Controller:
public function destroy($id){
Article::find($id)->delete();
//$article = Article::find($id);
return redirect()->back()->withErrors('Successfully deleted!');
}
Route:
Route::resource('article','ArticleController');
However, I think the problem lies in the default definition of database's name of your model. Laravel will assume that you have a database named blogs since you have a model named "blog". Are you having the database's name right?

To use DELETE HTTP Verb, your form should consists of the POST method and settings the method_field('DELETE')
Example:
<form method="POST" action="{{ route('xxx.destroy', $xxx->id) }}">
{{ csrf_field }}
{{ method_field('DELETE') }}
</form>

Related

cannot reference variable name "id" more than once

I need to delete booking by ID in my sub event id
Route::delete('event/{id}/booking/{id}', 'bookingController#destroy');
My Controller
public function destroy($id)
{
booking::destroy($booking->id);
return redirect('event')->with('flash_message', 'ลบข้อมูลการสำรองที่นั่งเรียบร้อย');
}
My from Method Delete
<form method="POST" action="{{ url('event/' . $event->id .'/booking/' . $booking->id) }}" accept-charset="UTF-8" style="display:inline">
{{ method_field('DELETE') }}
{{ csrf_field() }}
<button type="submit" class="btn btn-danger btn-sm" title="Delete event" onclick="return confirm("Confirm delete?")"><i class="fa fa-trash-o" aria-hidden="true"></i>ยกเลิกการจอง</button>
</form>
Your route has two variables (event_id) and (booking_id), yet your method only has one ($id)
Using your existing route (which is not tbh adhering to how eloquent works)
web.php
Route::delete('event/{event_id}/booking/{booking_id}', 'bookingController#destroy')->name('booking.destroy');
blade
action = "{{ route('booking.destroy', $event_id, $booking_id) }}"
controller
public function destroy ($booking_id, $event_id)
You might want to take a look at laravel relationships here:
https://laravel.com/docs/6.x/eloquent-relationships
Will make your life much easier, thus eloquent will pass an instance and your destroy method will look like this
public function destroy (Booking $booking)
{
$event = $booking->event();
// Do something with related event
// or vice versa
}
Are the IDs two separate IDs? Or do they share the same ID?
If they are two separate IDs, then you need to give them two explicitly different names, e.g. booking_id and event_id and then you would be able to access them in the Controller like you want.
Route::delete('event/{event_id}/booking/{booking_id}', 'bookingController#destroy');
Then in your controller you can do
public function destroy($event_id, $booking_id)
{
...
}
If I recall correctly, the parameters in the controller method do not need to be named the exact same as the ones in the route (although it'd make your life easier). The parameters are passed in order, so you could do
//$A = event_id, $B = booking_id
public function destroy($A, $B)
{
...
}

Laravel blade "undefined variable" error when using route()

As a project I am building a stackoverflow like forum. On the page on which a single question is shown I want the user to be able to click on the questioner's name and be forwarded to the respective user profile page. I am able to get the name from the database with {{ $question->user->name }}. The problem occurs when adding the part!
Also, the profile pages work. I can access them and the url then says for example: ../profile/1.
This is the route in the web.php file:
Route::get('/profile/{user}', 'PageController#profile')->name('profile');
This is the PageController part:
public function profile($id)
{
$user = User::with(['questions', 'answers', 'answers.question'])->find($id);
return view('profile')->with('user', $user);
}
This is the code from the show.blade View question page which does not work:
<p>
Submitted by {{ $question->user->name }}
</p>
The error message I get is Undefined variable: user.
Which surprises me because forwarding on the profile page to a specific question works with this blade code:
View Question
The respective route in the web.php file:
Route::resource('questions', 'QuestionController');
And QuestionController:
public function show($id)
{
$question = Question::findOrFail($id);
return view('questions.show')->with('question', $question);
}
I thought I defined the variable $user in the PageController like I defined $question in the QuestionController?
I can see you are using Eloquent models with relations. If you want to display the user id on the question, you can use the relation between the Question and User to find the id of the posting user.
Submitted by {{ $question->user->name }}
^^^^^^^^^
//just change your like this way
public function profile($id)
{
$user = User::with(['questions', 'answers', 'answers.question'])->find($id);
return view('profile',compact('user));
}

redirect a against different requests (laravel 5.3)

I am working on laravel 5.3
I want to redirect a user on different pages again from which page user is coming .
I have 3 pages one is
create
view all
view
I am using create page for create and edit purpose.
view all and view both page have edit button. after click it goes in Controller edit method and redirect to edit page in both cases.
Edit page have a return button. I want when user click on return it should go to view all if he comes from view all page to edit other wise if he came form view it should go back to view when he click on return.
Code for edit button is as in both view and view all pages is as
<li>
Edit
</li>
on click edit it comes here in controller edit method
public function edit($id){
$student = Student::findOrFail($id);
$data = ['action' => 'edit'];
return view('student.create')->with(compact('data', 'student'));
}
Buttons on create page are as right now
<div class="row">
<button type="submit" value="dd">Save and add</button>
#if ($data['action'] == 'edit')
<a href="{{ route('student.index') }}">
<button type="button">Return</button>
</a>
<button type="submit" value="edit">Save</button>
#endif
</div>
Now its returning me to view all students fine from update method because i use check there on button value as
if(Input::get('add')) {
return redirect()->route('student.create');
}else{
return redirect()->route('student.index');
}
How can i redirect to student.view on base of that user cam from student view to edit
Any idea how can i do it may be i also can work with session please help how to do
You can get the URI on the request using $uri = $request->path(); then use a switch the checks against $uri to dictate what to do next.
You will also need to modify your controllers head with
use Illuminate\Http\Request;
and update the edit method to public function edit(Request $request, $id){.
https://laravel.com/docs/5.3/requests#request-path-and-method
To return to the previous page/route in your controller use:
return redirect()->back();
Or simple:
return back();
Then you can have edit function like this:
public function edit($id)
{
$student = Student::findOrFail($id);
$data = [ 'action' => 'edit'];
return back()->with(compact('data', 'student'));
}
Ref: Laravel 5.2 doc - redirect
UPDATES:
If you mean it should go back after clicking the Return button then this should be enough:
Return
PS: I tested this on Laravel 5.2.* and it worked
I hope this helps :)
Use {{ URL::previous() }}
you can update your code like below
<button type="button">Return</button>

Laravel 5.1 Delete a row from database

I am trying to delete a category by clicking on a button
Blade:
<td class="center"><span class="glyphicon glyphicon-trash"></span></td>
Route:
Route::get('/deletecat/{name}','CategoryController#delete');
Controller:
public function delete($name)
{
category::find($name)->delete();
return Redirect::route('managecategory');
}
but I am getting an error while clicking on a button that
Call to a member function delete() on a non-object
Any help appreciated.
The ::find($id) method expects $id to be a number, the primary key of the row you want to find.
If you want to delete a row by name, you should use the following code:
category::where('name', $name)->delete();
The error is obviously because of the returned NON-OBJECT.
::find($name) returns an empty object or null
This is because the search was empty.
Make sure name is the primary key in order to use find.
Otherwise:
use ::where('name', $name)->delete();
or:
::where('name','=', $name)->delete();
*I pointed = because if you ever need to search different than = use >= <> and so on...
Secondly, it is not very important to use destroy. It is recommended but not a must-have!
In your view:
it has to be a form to submit a POST request like below:
<form action="/deletecat/{{$data->id}}" method="post">
#csrf
#method('DELETE')
<input type="submit" value="delete " >
</form>
Because this is POST Request has to use csrf and delete action.
In your route, it has be with delete() method,followwing with the controller.
Route::delete('/deletecat/{name}', 'CategoryController#destory');
In the controller:
public function destory($name)
{
category::find($name)->delete();
return Redirect::route('managecategory');
}
This is how laravel name format role:

Laravel 4 PHP: Routes Order Issue

EDIT:
I am using Laravel 4 PHP and initially I thought this problem was related to the 'link_to_route' method on a webpage so you can simply link to another webpage that does not contain any dynamic data.
However, I am discovering that the order you list your Routes will ultimately determine if your routes are successfully reached or not.
Authors2.php (Controller)
class Authors2_Controller extends BaseController {
public $restful = true;
public function contact() {
return View::make('authors2.index')
->with('title','Authors and Books')
->with('authors2', Author2::orderBy('name')->get());
}
public function getnew() {
return View::make('authors2.new')
->with('title', 'Add New Author');
}
Routes.php
Route::get('authors2', array('as'=>'authors2', 'uses' =>'Authors2_Controller#contact'));
Route::get('authors2/new', array('as'=>'new_author', 'uses'=>'Authors2_Controller#getnew'));
index.blade.php (view)
#extends('layouts.default')
#section('content')
<h1>Authors2 Home Page </h1>
<ul>
#foreach($authors2 as $author2)
<li>{{ link_to_route('author2', $author2->name, $parameters = array($author2->id)) }}</li>
#endforeach
</ul>
<p>{{ link_to_route('new_author', 'Add Author') }} </p>
#endsection
When I click on the 'Add Author' link, I get the error 'Trying to get property of non-object' error.
EDIT:
So now when I change the order of the routing where if I list the 'authors2/new' route BEFORE the 'authors2' route, the route will actually work:
Route::get('authors2/new', array('as'=>'new_author', 'uses'=>'Authors2_Controller#getnew'));
Route::get('authors2', array('as'=>'authors2', 'uses' =>'Authors2_Controller#contact'));
Does this have to deal with how Routes are first received and if so, why does this happen?
As mentioned by #Barry_127, Laravel will match routes based from most specific to least specific. So its good practice to list your routes in that order.

Categories