Laravel conflicting routes - php

My routes.php excerpt:
Route::group(['prefix' => 'admin', 'namespace' => 'Admin'], function() {
Route::resource('posts', 'PostsController', [
'except' => ['show']
]);
Route::delete('posts/trash', [
'as' => 'posts.trash.empty',
'uses' => 'PostsController#emptyTrash'
]);
});
My PostsController.php excerpt:
/**
* DELETE /admin/posts/{id}
*/
public function destroy($id)
{
// code
}
/**
* DELETE /admin/posts/trash
*/
public function emptyTrash()
{
// code
}
The problem is that Laravel confuses the 'trash' string in a DELETE /admin/posts/trash request as an {id} parameter. As a consequence, the destroy() method is called instead of emptyTrash(). Why and What can I do for this?

Firstly, order matters. Laravel will search the routes for a match in the order you register them. As you figured out, Laravel will take trash as an id and therefore the URI matches the resource route. Since that route is registered before your additional one, it will use the resource route.
The simplest fix is to just change that order:
Route::delete('posts/trash', [
'as' => 'posts.trash.empty',
'uses' => 'PostsController#emptyTrash'
]);
Route::resource('posts', 'PostsController', [
'except' => ['show']
]);
If you don't like that you can try to limit the parameter for your resource route to numbers only. Unfortunately you can't just add a ->where() to the resource route like you could with others.
Instead you have to define a global pattern for the route parameter. The route parameter Route::resource chooses is the resource name (in snake_case).
So this should work for you:
Route::pattern('posts', '[0-9]+');

Somewhere in your view, you should have a button or a link for actually deleting the post. The view should look something like this:
#section('content')
<div class="panel panel-default">
<div class="panel-heading clearfix">
<b>{{ $post->post_name . ' (id:' . $post->post_id . ')' }}</b><br />
<b> {{ link_to_route('overview', 'Go Back To Post List') }} </b>
<div class="pull-right">
// FORM FOR DELETING POST
{{ Form::open(array('route' => array('delete_post', $post->post_id))) }}
{{ link_to_route('edit_post', 'Edit Post', array('id' => $post->post_id), array('class' => 'post_img_button_edit')) }}
{{ Form::hidden('_method', 'DELETE') }}
{{ Form::submit('Delete Post', array('class' => 'post_img_button_delete')) }}
{{ Form::close() }}
</div>
<div class="pull-right">
// FORM FOR EMPTYING TRASH
{{ Form::open(array('route' => 'empty_trash')) }}
{{ Form::hidden('_method', 'DELETE') }}
{{ Form::submit('Empty Trash', array('class' => 'post_img_button_delete')) }}
{{ Form::close() }}
</div>
</div>
/* Additional HTML code within view */
Your controller should be similar to this:
public function destroy($id)
{
$this->post->delete($id);
return \Redirect::route('overview');
}
public function emptyTrash()
{
// code for collecting and emptying Trash
}
And your routes should look similar to this:
Route::delete('admin_posts/admin_posts/{id}/destroy', array('as'=>'delete_post', 'uses'=>'PostsController#destroy'));
Route::delete('posts/trash', array('as'=>'empty_trash', 'uses'=>'PostsController#emptyTrash'));
The name of your route for actually deleting posts be 'delete_post'.
The name of your route for emptying your trash will be empty_trash
Basically you're explicitly defining your routes so that you'll avoid less ambiguity and Laravel will know which routes to take. Hopefully this information will help!

Related

I change routes on resources and my tournaments pages are empty. LARAVEL 8

Hi a used every controller method as one after i created store method so i change it on Route::resource, i wanted translate routes names so i used AppService provider and add Slovakian language to routes but now i have problem and my routes are good but it doesn't work. I have every tournament page empty and slugs that are not used working with empty page too. On empty page is navbar and my blade without data from DB.
Thanks for advices.
One the my methods in controller for example
public function show(Tournament $tournament)
{
return view('tournaments.show', [
'tournament' => $tournament,
'regions' => Region::where("id", "=", $tournament->region_id)->get(),
]);
}
My routes
Route::resource('turnaje', TournamentController::class)
->parameters([
'tournaments' => 'tournaments:slug'
])->only([
'create', 'store', 'edit', 'update', 'destroy'
])->middleware('auth');
Route::resource('turnaje', TournamentController::class)
->only([
'index', 'show',
]);
AppServiceProvider
public function boot()
{
Route::resourceVerbs([
'create' => 'pridat',
'edit' => 'editovat',
]);
}
My blade
div class="container mx-auto">
<h1 class="title text-center text-4xl pt-8">{{ $tournament->title }}</h1>
<h2 class="title text-2xl">{{ $tournament->city }}</h2>
<h3>{{ $tournament->street }}</h3>
<p class="mt-8">{!! $tournament->text !!}</p>
</div>
If you find something better, it could be like this maybe
Route::get('/turnaje', [TournamentController::class, 'index']);
Route::get('/turnaj/pridat', [TournamentController::class, 'create'])
->middleware('auth');
Route::get('/turnaj/{tournament}', [TournamentController::class, 'show']);
Route::resource('turnaje', TournamentController::class)->parameters([
'tournaments' => 'tournaments:slug'
])->except(['index', 'show', 'create'])->middleware('auth');

Trying to get property of non-object laravel when accessing database

I am trying to code the edit route for laravel and for some reason keep getting the error "Trying to get property of non-object laravel". The Create controller works fine, however when I use the controller#update route I keep getting this error
My Controller for adding an event: (update)
public function update(Request $request, $id)
{
//create event
$my_user = my::find($id);
$my_user->programme = $request->input('programme');
$my_user->goal1 = $request->input('goal1');
$my_user->goal2 = $request->input('goal2');
$my_user->goal3 = $request->input('goal3');
$my_user->goal4 = $request->input('goal4');
$my_user->goal5 = $request->input('goal5');
$my_user->user_id = auth()->user()->id;
$my_user->save();
return redirect('/home')->with('success','Event Created');
}
edit page
#extends('layouts.app')
#section('content')
<div class="container">
<h1>Edit Post</h1>
{!! Form::open(['action' => ['myUserController#update', $my_user], 'method' => 'POST']) !!}
<div class="form-group">
{{Form::label('title', 'Event Name')}}
{{Form::text('goal1', $my_user->goal1, ['class' => 'form-control', 'placeholder' => 'Goal One'])}}
</div>
{{Form::hidden('_method','PUT')}}
{{Form::submit('Submit', ['class'=>'btn btn-primary'])}}
{!! Form::close() !!}
</div>
#endsection
Given that you are using a Route::resource you can type-hint your parameters by writing something like
public function update(Request $request, MyUser $myuser){
// The $myuser parameter comes from the Route::resource and can be verified using php artisan route:list in your terminal
// edit $my_user
$my_user->save();
return redirect('/home')->with('success','Event Created');
}
Update after reviewing LaravelCollective documentation for Form
Thank you Sohel0415 for mentioning that you do not need to call $my_user->id for providing the route parameter with the Form facade.
You can use this method on your code:
{{ Form::open(array('url'=>'admin/users/store' , 'method' =>'POST')) }}
and your route define by this method in web.php file:
Route::post('users/store', 'admin\UserController#store');

Laravel Form Model Binding not submitting

I'm having some trouble using form model binding with L4. My form is being populated, and the routes are correct but it's not submitting correctly.
Controller:
public function edit($id)
{
$transaction = Transaction::where('id', '=', $id)->get();
return View::make('transaction')->with('transactions', $transaction);
}
public function update($id)
{
$transaction = Transaction::find($id);
$input = Input::all();
$transaction->status = $input['status'];
$transaction->description = $input['description'];
$transaction->save();
}
View:
#foreach($transactions as $transaction)
{{ Form::model($transaction, array('route' => array('transactions.update', $transaction->id))); }}
{{ Form::text('description'); }}
{{ Form::select('status', array('R' => 'Recieved', 'S' => 'Shipped', 'P' => 'Pending'), 'R'); }}
{{ Form::submit('Submit'); }}
{{ Form::close(); }}
#endforeach
I'm assuming that your transactions.* routes are being generated via Route::resource().
Per the documentation, Laravel generates the following routes for a resource:
Verb Path Action Route Name
GET /resource index resource.index
GET /resource/create create resource.create
POST /resource store resource.store
GET /resource/{resource} show resource.show
GET /resource/{resource}/edit edit resource.edit
PUT/PATCH /resource/{resource} update resource.update
DELETE /resource/{resource} destroy resource.destroy
You'll see that resource.update is expecting a PUT/PATCH request, but Laravel forms default to POST.
To fix this, add 'method' => 'PUT' to the array of form options, like so:
{{ Form::model($transaction, array(
'method' => 'PUT',
'route' => array('transactions.update', $transaction->id)
)); }}
This will add a hidden input, <input type="hidden" name="_method" value="PUT" />, to your form which tells Laravel to spoof the request as a PUT.

Upon seemingly correct routing getting error Route not defined! - Laravel 4

I'm developing a very basic application using Laravel 4.1 where users can signup and ask question, pretty basic stuffs. I'm now a bit confused about the restful method which would look something like this public $restful = true in laravel 3. Since then laravel has changed a lot and I got stucked with the restful idea. So I decided to leave it and go on developing the skeleton of my application. Everything went well until I created the postCreate method in my homeController to let authorized users submit their question through a form. I believe I routed the method correctly and the index.blade.php view is alright as well. I just can't figure out why I'm getting this following error even though the codes seem to be okay.
Route [ask] not defined. (View: C:\wamp\www\snappy\app\views\questions\index.blade.php)
If you have got what I'm doing wrong here would appreciate if you point it out with a little explanation.
I'm totally new in laravel 4 though had a bit of experience in the previous version.
Here's what I have in the HomeController.php
<?php
class HomeController extends BaseController {
public function __construct() {
$this->beforeFilter('auth', array('only' => array('postCreate')));
}
public function getIndex() {
return View::make('questions.index')
->with('title', 'Snappy Q&A-Home');
}
public function postCreate() {
$validator = Question::validate(Input::all());
if ( $validator->passes() ) {
$user = Question::create( array (
'question' => Input::get('question'),
'user_id' => Auth::user()->id
));
return Redirect::route('home')
->with('message', 'Your question has been posted!');
}
return Redirect::route('home')
->withErrors($validator)
->withInput();
}
}
this is what I have in the routes.php file
<?php
Route::get('/', array('as'=>'home', 'uses'=>'HomeController#getindex'));
Route::get('register', array('as'=>'register', 'uses'=>'UserController#getregister'));
Route::get('login', array('as'=>'login', 'uses'=>'UserController#getlogin'));
Route::get('logout', array('as'=>'logout', 'uses'=>'UserController#getlogout'));
Route::post('register', array('before'=>'csrf', 'uses'=>'UserController#postcreate'));
Route::post('login', array('before'=>'csrf', 'uses'=>'UserController#postlogin'));
Route::post('ask', array('before'=>'csrf', 'uses'=>'HomeController#postcreate')); //This is what causing the error
And finally in the views/questions/index.blade.php
#extends('master.master')
#section('content')
<div class="ask">
<h2>Ask your question</h2>
#if( Auth::check() )
#if( $errors->has() )
<p>The following erros has occured: </p>
<ul class="form-errors">
{{ $errors->first('question', '<li>:message</li>') }}
</ul>
#endif
{{ Form::open( array('route'=>'ask', 'method'=>'post')) }}
{{ Form::token() }}
{{ Form::label('question', 'Question') }}
{{ Form::text('question', Input::old('question')) }}
{{ Form::submit('Ask', array('class'=>'btn btn-success')) }}
{{ Form::close() }}
#endif
</div>
<!-- end ask -->
#stop
Please ask if you need any other instance of codes.
Your 'ask' route is not named. When you pass 'route' => 'foo' to Form::open, that assumes you have a route named 'foo'. add 'as' => 'ask' to your /ask route and it should work.
Alternatively, use URL or Action to resolve the form's target url instead:
Form::open(['url' => 'ask']);
Form::open(['action' => 'HomeController#postCreate']);
you are using name route ask in your form which is not exist. I have created the name route ask for you.
Route::post('ask', array('before'=>'csrf', 'as' => 'ask', 'uses'=>'HomeController#postcreate'));
{{ Form::open( array('route'=>'ask', 'method'=>'post')) }}
^^^^ -> name route `ask`
{{ Form::token() }}

Can't pass a parameter through a named route

I cant figure out what I am missing. I am trying to have a form submit to a controller method through a named route with all of its input and image->id as a parameter. I keep getting a notfoundhttpexception. If I remove /{$id} from the route declaration I get a missing parameter for controller action error. Here is the code:
The route
Route::post('images/toalbum/{$id}', array('as' => 'imgToAlbum', 'uses' => 'ImagesController#addImageToAlbums'));
routes.php
<?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 Closure to execute when that URI is requested.
|
*/
Route::get('/', array('as' => 'home', function()
{
return View::make('layouts.default');
}));
Route::get('users/login', 'UsersController#getLogin');
Route::get('users/logout', 'UsersController#getLogout');
Route::post('users/login', 'UsersController#postLogin');
Route::resource('users', 'UsersController');
Route::resource('images', 'ImagesController');
//routes related to images
Route::post('images/toalbum/{$id}', array('as' => 'imgToAlbum', 'uses' => 'ImagesController#addImageToAlbums'));
Route::resource('videos', 'VideosController');
Route::resource('albums', 'AlbumsController');
view that's submitting the form:
#extends('layouts.default')
#section('content')
<?php
$albumarray = array(null => '');
?>
{{ HTML::image($image['s3Url'], $image['altText']) }}
<p>
Title:{{ $image['caption'] }}</br>
Alt-Text: {{ $image['altText'] }}</br>
Description: {{ $image['description'] }}</br>
</p>
{{ Form::open(array('route' => array('imgToAlbum', $image['id']), 'method' => 'post')); }}
#foreach ($albums as $album)
<?php
array_push ($albumarray, array($album['id'] => $album['caption']));
?>
#endforeach
{{ Form::label('Add image to album?') }}
{{ Form::select('album', $albumarray) }}</br>
{{ Form::submit('Add to Album')}}
{{Form::close();}}
<?php
echo $albums;
?>
#stop
#section('footer')
#stop
controller:
<?php
class ImagesController extends BaseController
{
protected $image;
public function __construct(Image $image)
{
$this->image = $image;
}
// add image to album
public function addImageToAlbums($id)
{
dd($album = Input::all());
$image = $this->where('id', '=', $id);
$image->albumId = $album;
$this->image->save();
/*return Redirect::route('image.show', $this->image->id)
->with('message', 'Your image was added to the album');*/
}
}
Maybe this will help someone in the future so instead of deleting here is the answer. removing the $ from images/toalbum/{$id} in the route declaration has resolved the problem.

Categories