so, the view page already display all data. but there is an error "not found exception" when the delete button will be pressed. URL that showed in my browser when i press delete button is "http://localhost:8000/admin/hapusdataruang/69"
This is the view page
<table id="datatable-buttons" class="table table-striped table-bordered">
<thead>
<tr>
<th>ID Ruang</th>
<th>Nama Ruangan</th>
<th>Keterangan</th>
<th>Aksi</th>
</tr>
</thead>
<tbody>
#foreach($showruang as $rooms)
<tr>
<td>{{$rooms->id_ruang}}</td>
<td>{{$rooms->nm_ruang}}</td>
<td>{{$rooms->keterangan}}</td>
<td>
<form action="{{ url('/admin/hapusdataruang', $rooms->id_ruang) }}" method="post">
{{ csrf_field() }}
{{ method_field('DELETE') }}
Edit
<button class="btn btn-sm btn-danger" type="submit" onclick="return confirm('Yakin ingin menghapus data?')">Delete</button>
</form>
</td>
</tr>
#endforeach
</tbody>
This is the AdminController
public function destroyruang($id_ruang)
{
$ruang = Ruang::where('id_ruang',$id_ruang)->first();
$ruang->delete();
return redirect(url('/admin/dataruang'));
}
This is the admin route
Route::post('/hapusdataruang', 'AdminController#destroyruang', function () {
$users[] = Auth::user();
$users[] = Auth::guard()->user();
$users[] = Auth::guard('admin')->user();
//dd($users);
})->name('destroydataruang');
This is Ruang Model
use Illuminate\Database\Eloquent\Model;
namespace App;
class Ruang extends Model
{
protected $table = 'tr_ruang';
protected $primaryKey = 'id_ruang';
protected $dates = ['deleted_at'];
protected $fillable = ['keterangan','nm_ruang'];
}
The problem is in your routes file. You are submitting the form via a POST request to this url /admin/hapusdataruang, but you have {{ method_field('DELETE') }} in your form, so your route needs to be able to accept DELETE requests.
Your code:
Route::post('/hapusdataruang', 'AdminController#destroyruang', function () {
is for POST requests, not DELETE requests, so change it to:
Route::delete('/hapusdataruang', 'AdminController#destroyruang', function () {
change this code
Route::post('/hapusdataruang', 'AdminController#destroyruang', function () {
to
Route::delete('/hapusdataruang', 'AdminController#destroyruang', function () {
If You want to use the POST Request for deleting an entry from your database then you don't have to specify {{ method_field('DELETE') }} in your form, if you remove this from your form declaration then your existing route will work, but if you want to use the DELETE Request then you have to specify the Route as Route::delete('/yourpath','ControllerName#methodname');
Related
I'm working with Laravel 8 and I have made a table like this at Blade:
<div class="card-body table-responsive p-0">
<table class="table table-hover">
<tr>
<th>Username</th>
<th>Email</th>
<th>Role</th>
<th>Actions</th>
</tr>
#foreach($roles as $role)
#if(count($role->users))
#foreach($role->users as $user)
<tr>
<td>{{ $user->name }}</td>
<td>{{ $user->email }}</td>
<td>{{ $role->name }} | {{ $role->label }}</td>
<td>
<form action="{{ route('levels.destroy' ,$user->id) }}" method="post">
#method('DELETE')
#csrf
<div class="btn-group btn-group-xs">
Edit
<button type="submit" class="btn btn-danger">Delete</button>
</div>
</form>
</td>
</tr>
#endforeach
#endif
#endforeach
</table>
</div>
And the result perfectly showing up:
But now I got problem with Edit & Delete buttons that I have specified $user->id as parameter for both of them.
And when I hover over the buttons I can see the user id properly defined:
But when it comes to edit method which is using Route Model Binding, it does not find the user:
public function edit(User $user)
{
dd($user->id); // return null
}
However if I do not use Route Model Binding and say this instead:
public function edit($id)
{
dd($id); // return 1
}
It properly shows the user id!
I don't know why the Route Model Binding not working here, so if you know what's going wrong or how to fix this issue, please let me know...
You are trying to access the User Model which in this case doesn't know what id is, so you should be passing the id of the user to the edit route using either Get by passing it to the url endpoint , so now you can get it like
public function edit($id)
{
dd($id); // return null
}
or by sending it as a POST form and get it like
public function edit(Request $request)
{
dd($request->id); // return null
}
I saw comments, your resource controller name is not matching with your variable name "$user".
You can look here on official laravel docs.
In your situation, this might help;
Route::resource('levels', LevelController::class)->parameters([
'levels' => 'user'
]);
I have a view that show some data and have edit feature, but when clicked edit button, user will be redirected to http://localhost:8000/posts/2/edit, I dont want post id appear in the URL, what should I do?
<table class="table table-bordered">
<tr>
<th width="20px" class="text-center">No</th>
<th>Title</th>
<th>Content</th>
<th width="280px" class="text-center">Action</th>
</tr>
#foreach ($posts as $post)
<tr>
<td class="text-center">{{ ++$i }}</td>
<td>{{ $post->title }}</td>
<td>{{ $post->content }}</td>
<td class="text-center">
<form action="{{ route('posts.destroy',$post->id) }}" method="POST">
<a class="btn btn-info btn-sm" href="{{ route('posts.show',$post->id) }}">Show</a>
<a class="btn btn-primary btn-sm" href="{{ route('posts.edit',$post->id) }}">Edit</a>
#csrf
#method('DELETE')
<button type="submit" class="btn btn-danger btn-sm" onclick="return confirm('Delete?')">Delete</button>
</form>
</td>
</tr>
#endforeach
</table>
here is the controller
public function edit(Post $post)
{
return view('posts.edit', compact('post'));
}
here is the route
Route::get('/', function () {
return view('welcome');
});
Route::resource('posts', App\Http\Controllers\PostController::class);
Auth::routes();
Thanks in advance
If you want to prevent users to edit posts that they did not create:
public function edit(Post $post)
{
if(Auth::user()->id != $post->user_id) {
throw new \Exception("Access denied", 403);
}
return view('posts.edit', compact('post'));
}
you need to use the Auth class offcourse:
use Illuminate\Support\Facades\Auth;
You need to do the same for the delete function
why you don't the id to appear in url. i can not see the reason to do that because there should be some unique key to edit the post. the only way i see is to add in the database a slug column and put it as unique. when adding a post put the title replacing space with '_' as a slug. make sure it is unique in validation. and in your edit and show code send the slug instead of the id.
route('posts.edit',$post->slug)
don't use dependency injection in controller
public function edit( $slug)
{
$post = Post::where('slug','=',$slug)->first();
return view('posts.edit', compact('post'));
}
hi
I think it will help you
your route will be like this:
Route::resource('posts', App\Http\Controllers\PostController::class)->except([
'edit'
]);
or
Route::resource('posts', App\Http\Controllers\PostController::class, ['only' => ['index', 'destroy', 'update' , 'create' , 'store']]);
or even you can write each route separately...
and write your edit route, separate :
Route::post('/post/edit', [App\Http\Controllers\PostController::class, "edit"])->name('post.edit');
delete #method('DELETE') from your blade and add this input to your blade :
<input type="hidden" name="post_id" value="{{$post->id}}" />
and change this :
public function edit(Post $post)
{
return view('posts.edit', compact('post'));
}
to this :
public function edit(Request $request)
{
$post_id = $request->post_id;
//write your code here
return view('posts.edit', compact('post'));
}
I've been working on the search function for my library application, which is my first Laravel project so I am kinda struggling.
I have finally figured out the search function, where I can search for a book by its title, however, I can't display any data from the search that is not in that table.
If I run the search I get the following error message:
Facade\Ignition\Exceptions\ViewException
Undefined property: stdClass::$authors (View: /Users/krisz/code/project/resources/views/books/index.blade.php)
I have created a pivot table between 'books' and 'authors' and if I want to display the data only on my index page without searching it works, but after searching I cannot get it to work.
Also, if I delete all the data from my index.blade.php which is outside the "books" table the search works correctly.
Could you please help me with this problem?
BookController:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Book;
use App\Language;
use App\Genre;
use App\Author;
use App\Publisher;
use App\User;
use Illuminate\Support\Facades\DB;
class BookController extends Controller
{
public function index(Request $request)
{
$books = Book::with('language')->get();
$books = Book::with('user')->get();
$languages = Language::all();
$genres = Genre::all();
$publishers = Publisher::all();
$users = User::all();
$authors = Author::all();
return view('books/index', compact('books','languages','genres','publishers','users'));
}
public function search(Request $request)
{
$authors = Author::all();
$books = Book::with('language')->get();
$books = Book::with('user')->get();
$languages = Language::all();
$genres = Genre::all();
$publishers = Publisher::all();
$users = User::all();
$search = $request->get('search');
$books = DB::table('books')
->where('title','like','%' .$search. '%')
->paginate(5);
return view('books/index')
->with(compact('books','languages','genres','authors','publishers','users'));
}
}
index.blade.php:
#extends('layout')
#section('title')
<title>Alle Bücher</title>
#section('content')
<style>
.uper {
margin-top: 40px;
}
</style>
<div class="uper">
#if(session()->get('success'))
<div class="alert alert-success">
{{ session()->get('success') }}
</div><br />
#endif
<div align="left">
<div class="col-md-4">
<h1>Policy</h1>
</div>
<div class="col-md-4">
<form action="{{ route('search') }}" method="get" role="search">
{{ csrf_field() }}
<div class="input-group">
<input type="text" class="form-control" name="search" placeholder="Search Title" <span class="input-group-btn">
<button type="submit" class="btn btn-primary">Search</button></span>
</div>
</form>
</div>
</div>
<table class="table table-hover">
<thead>
<tr>
<td>ID</td>
<td>Titel</td>
<td colspan="2">Autor</td>
<td>Jahr</td>
<td colspan="2">Verlag</td>
<td colspan="2">Genre</td>
<td>Sprache</td>
<td>ISBN</td>
<td>Seitenzahl</td>
<td>Ausgeliehen von:</td>
<td colspan="2">Funktionen</td>
</tr>
</thead>
<tbody>
#foreach($books as $book)
<tr>
<td>{{$book->id}}</td>
<td>{{$book->title}}</td>
#foreach($book->authors as $author)
<td>{{$author->name}}</td>
#endforeach
<td>{{$book->year}}</td>
#foreach($book->publishers as $publisher)
<td>{{$publisher->name}}</td>
#endforeach
#foreach($book->genres as $genre)
<td>{{$genre->name}}</td>
#endforeach
<td>{{$book->language->name}}</td>
<td>{{$book->isbn}}</td>
<td>{{$book->pages}}</td>
<td>{{$book->user->name}}</td>
<td>Bearbeiten</td>
<td>
<form action="{{ route('books.destroy', $book->id)}}" method="post">
#csrf
#method('DELETE')
<button class="btn btn-danger" type="submit">Löschen</button>
</form>
</td>
</tr>
#endforeach
</tbody>
</table>
<div>
#endsection
Book Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Book extends Model
{
protected $fillable = ['title', 'year', 'language_id', 'isbn', 'pages', 'user_id'];
public function publishers(){
return $this->belongsToMany(Publisher::class);
}
public function authors(){
return $this->belongsToMany(Author::class);
}
public function genres(){
return $this->belongsToMany(Genre::class);
}
public function language(){
return $this->belongsTo(Language::class);
}
public function user(){
return $this->belongsTo(User::class);
}
}
First, you're just overwriting yourself here:
$books = Book::with('language')->get();
$books = Book::with('user')->get();
I suspect you want both language and user, and you probably want the authors, as well as some other data you try to fetch in the view? This is called eager loading and it's done on multiple relationships like this:
$books = Book::with(['language', 'user', 'authors', 'publishers', 'genres'])->get();
Not sure about the error you're getting, as $book should be an instance of App\Book and not stdClass, and relations should still be available even if not eager loaded. I suspect there's some code you're not showing or your models are not defined correctly.
Hi I am currently making an app with a simple CRUD operation and I am bothered why my code isn't deleting a record whenever I press the delete button. I am a newbie in Laravel and Vue and currently familiarizing the functions and workflows of the 2 frameworks. I have a table called posts and it contains id, title and body. The app will add a new post and also edits the post and deletes a record. But what actually happened is that the app does not delete a record and I am not sure if a button must bind in order to pass the id to the controller. Can you help me please?
Here is my vue page (IndexComponent.vue):
<template>
<div>
<h1>Posts</h1>
<div class="row">
<div class="col-md-10"></div>
<div class="col-md-2">
<router-link :to="{ name: 'create' }" class="btn btn-primary">Create Post</router-link>
</div>
</div><br />
<table class="table table-hover">
<thead>
<tr>
<th>ID</th>
<th>Item Name</th>
<th>Item Price</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="post in posts" :key="post.id">
<td>{{ post.id }}</td>
<td>{{ post.title }}</td>
<td>{{ post.body }}</td>
<td><router-link :to="{name: 'edit', params: { id: post.id }}" class="btn btn-primary">Edit</router-link></td>
<td><button class="btn btn-danger">Delete</button></td>
</tr>
</tbody>
</table>
<script>
import axios from 'axios';
export default {
data(){
return {
posts: []
}
},
created(){
let uri = "/api/posts";
axios.get(uri).then(response => {
this.posts = response.data.data;
});
},
methods: {
deletePost(id) {
let uri = `/api/post/delete/${id}`;
axios.delete(uri).then(response => {
this.posts.splice(this.posts.indexOf(id), 1);
});
}
}
}
This is what's inside my PostController.php :
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Resources\PostCollection;
use App\Post;
public function delete($id) {
$post=Post::find($id);
$post->delete();
return response()->json('Successfully deleted!');
}
This will be my Route:
Route::delete('/post/delete/{id}', 'PostController#delete');
Inside my Post.php (Model):
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $fillable = ['title', 'body'];
}
Everything is actually working except the delete operation and I am still bothered until now. I haven't worked any solution to this problem.
AND BY THE WAY: For the UI. i am using bootstrap 4.3.1 and bootstrap-vue 2.0.4
<tr v-for="post in posts" :key="post.id">
<td>{{ post.id }}</td>
<td>{{ post.title }}</td>
<td>{{ post.body }}</td>
<td><router-link :to="{name: 'edit', params: { id: post.id }}" class="btn btn-primary">Edit</router-link></td>
<td><button #click="deletePost(post.id)" class="btn btn-danger">Delete</button></td>
</tr>
The reason why it is not deleting because you're not trigging the deletePost function. You should call it on the click event like the code above.
I'm using Laravel 5.2 and trying to do an add and delete a data that I already Inputted but when i clicked "Delete" button it gave me NotFoundHttpException.
Here's example of my delete function code in controller:
<?php
namespace App\Http\Controllers\Track;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
//use Illuminate\Support\Facades\Input;
use Validator;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Track as Track;
class TrackController extends Controller
{
/*Display track registry*/
public function index()
{
$data = array('track' => Track::all());
return view('admin.dashboard.tracks.track',$data);
}
/*Display create track form*/
public function create()
{
return view('admin.dashboard.tracks.createtrack');
}
/*Save data form*/
public function saveTrack(Request $request)
{
$input = $request->all();
$messages = array(
'trackCode.required'=>'Track code required.',
'trackCode.unique'=>'Track code already exist.',
'trackName.required'=>'Track name required.',
);
$rule = array(
'trackCode' => 'required|unique:track',
'trackName' => 'required|max:60',
);
$validator = Validator::make($input, $rule, $messages);
if($validator->fails()) {
#Directed to the same page with error message
return Redirect::back()->withErrors($validator)->withInput();
#Validate Success
}
$track = new Track;
$track->trackCode = $request['trackCode'];
$track->trackName = $request['trackName'];
if (! $track->save())
App::abort(500);
return Redirect::action('Track\TrackController#index')->with('successMessage','Track data "'.$input['trackName'].'" has been inserted.');
}
/*Delete data*/
public function delete($id)
{
echo $id;
/*$trackCode = Track::where('trackCode','=',$id)->first();
if($trackCode==null)
App::abort(404);
$trackCode->delete();
return Redirect::action('track');*/
}
}
and here's the part of my delete option code:
<div class="box-body">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th style="width: 150px; text-align: center;">Track Code</th>
<th>Track Name</th>
<th>Action</th>
</tr>
</thead>
<tbody>
#foreach($track as $itemTrack)
<tr id="track-list" name="track-list">
<td style="text-align: center;">{{ $itemTrack->trackCode }}</td>
<td>{{ $itemTrack->trackName }}</td>
<td><a href="{{{ action('Track\TrackController#delete',[$itemTrack->trackCode]) }}}" title="Delete" onclick="return confirm('Are you sure you want to delete this track : {{{$itemTrack->trackCode.' - '.$itemTrack->trackName }}}?')">
<span class="label label-danger"><i class="fa fa-trash"> Delete </i></span>
</a>
</td>
</tr>
#endforeach
</tbody>
</table>
<br/>
<button class="btn btn-success pull-right" type="submit">Add Data</button>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
whenever it appears the data and i try to delete it, it went to a page and there's NotFoundHttpException error instead of showing me the $id of the data.
Can someone help and explain? thanks
-Edited part-
Routes:
<?php
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the controller to call when that URI is requested.
|
*/
Route::get('/', function () {
return view('welcome');
});
Route::group(['middleware' => 'web'], function()
{
Route::auth();
});
//Route as admin
Route::group(['middleware' => ['web','role:admin']], function()
{
Route::get('/users/dashboard', 'UserController#index');
/*-----------------------------------------------Track Part---------------------------------------------------------*/
/*Track index*/
Route::get('/users/programs/track', array('as'=>'track', 'uses'=>'Track\TrackController#index'));
/*Create track form*/
Route::get('/users/programs/track/create', array('as'=>'track.create', 'uses'=>'Track\TrackController#create'));
/*Route to save track*/
Route::post('/users/programs/track/save', array('as'=>'track.save', 'uses'=>'Track\TrackController#saveTrack'));
/*Delete track*/
Route::get('/users/programs/track/{$id}/delete', array('as'=>'track.delete', 'uses'=>'Track\TrackController#delete'));
/*-----------------------------------------------Course Part---------------------------------------------------------*/
//Display course menu
Route::get('/users/programs/course', array('as'=>'course', 'uses'=>'Course\CourseController#index'));
//Delete course data
Route::get('/users/programs/course/{$id}/delete', array('as'=>'course.delete', 'uses'=>'Course\CourseController#delete'));
//Create course data
Route::post('/users/programs/course/create', array('as'=>'course.create', 'uses'=>'Course\CourseController#createCourse'));
//Edit course data
Route::get('/users/programs/course/{$id}/edit', array('as'=>'course.edit', 'uses'=>'Course\CourseController#editCourse'));
//Save editted course data
Route::put('/users/programs/course/{$id}/saveEdit', array('as'=>'course.saveEdit', 'uses'=>'Course\CourseController#saveEdit'));
});
I'm guessing that you are using DELETE in your route, which wouldn't work with an a link. You'd need to create a form and spoof the DELETE. You can find more about doing it here.
Alternatively, you can change Route::delete() to Route::get(), but this isn't recommended.
I think this could be do to with your triple braces. Try {{ action('Track\TrackController#create') }} instead.
More information read this link
Try this:
{!! action('track.delete',[$itemTrack->trackCode]) !!}
From documentation:
"If the method accepts route parameters, you may pass them as the second argument to the method:
$url = action('UserController#profile', ['id' => 1]);"
I guess 'id' wasn`t defined properly. Try this:
action('Track\TrackController#delete',['id' => $itemTrack->trackCode])
Replace delete Anchor tag with this:-
<a href="{{ url('users/programs/track/'.$itemTrack->trackCode.'/delete') }}" title="Delete" onclick="return confirm('Are you sure you want to delete this track : {{{$itemTrack->trackCode.' - '.$itemTrack->trackName }}}?')">
And change the delete Route:-
Route::match(['get', 'post'], '/users/programs/track/{id?}/delete', 'Track\#TrackController#delete');
Hope it Helps!