Chris Chris - 9 days ago 7
PHP Question

Laravel 5.2 Route not working when using resource for CRUD operation

I am attempting to get familiar with the Laravel framework. I have been following a tutorial and am stuck at a portion with routing. I have a simple Blog project that is attempting to create and edit a blog post. I already have 2 other objects CRUD operations working correctly - 1 of them is setup with a resource in the routes just like I am trying to do with this one. When attempting to make a post to the following:

<form class="form-horizontal" role="form" method="POST"
action="{{ route('admin.post.store') }}">


I am returned an error "Route [admin.post.store] not defined. (View: /home/vagrant/Code/test-dev/resources/views/admin/post/create.blade.php)"

Now I am understanding that this is an issue with it being able to find the "store" procedure stored by default in the base class of my model post object. I used artisan and migration to create these objects and automatically tie them to the DB objects. Post.php model object posted below:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
protected $dates = ['published_at'];
protected $fillable = [
'title', 'subtitle', 'content_raw', 'page_image', 'meta_description',
'layout', 'is_draft', 'published_at',
];

//// other methods here that help pass slug and do DB relationship support
//// If someone thinks they are relevant I can addthem
}


Here is the web.php file inside of the "routes" folder:

Route::get('/', function () {
return redirect('/blog');
});

Route::get('blog', 'BlogController@index');
Route::get('blog/{slug}', 'BlogController@showPost');

// Admin area
Route::get('admin', function () {
return redirect('/admin/post');
});
$router->group([
'namespace' => 'Admin',
'middleware' => 'auth',
], function () {
Route::resource('admin/post', 'PostController', ['except' => 'show']);
Route::resource('admin/tag', 'TagController', ['except' => 'show']);
Route::get('admin/upload', 'UploadController@index');
Route::post('admin/upload/file', 'UploadController@uploadFile');
Route::delete('admin/upload/file', 'UploadController@deleteFile');
Route::post('admin/upload/folder', 'UploadController@createFolder');
Route::delete('admin/upload/folder', 'UploadController@deleteFolder');
});

Auth::routes();

Route::get('/home', 'HomeController@index');


Here is the PostController

<?php
namespace App\Http\Controllers\Admin;

use App\Jobs\PostFormFields;
use App\Http\Requests;
use App\Http\Requests\PostCreateRequest;
use App\Http\Requests\PostUpdateRequest;
use App\Http\Controllers\Controller;
use App\Post;

class PostController extends Controller
{
/**
* Display a listing of the posts.
*/
public function index()
{
return view('admin.post.index')
->withPosts(Post::all());
}

/**
* Show the new post form
*/
public function create()
{
$data = $this->dispatch(new PostFormFields());

return view('admin.post.create', $data);
}

/**
* Store a newly created Post
*
* @param PostCreateRequest $request
*/
public function store(PostCreateRequest $request)
{
$post = Post::create($request->postFillData());
$post->syncTags($request->get('tags', []));

return redirect()
->route('admin.post.index')
->withSuccess('New Post Successfully Created.');
}

/**
* Show the post edit form
*
* @param int $id
* @return Response
*/
public function edit($id)
{
$data = $this->dispatch(new PostFormFields($id));

return view('admin.post.edit', $data);
}

/**
* Update the Post
*
* @param PostUpdateRequest $request
* @param int $id
*/
public function update(PostUpdateRequest $request, $id)
{
$post = Post::findOrFail($id);
$post->fill($request->postFillData());
$post->save();
$post->syncTags($request->get('tags', []));

if ($request->action === 'continue') {
return redirect()
->back()
->withSuccess('Post saved.');
}

return redirect()
->route('admin.post.index')
->withSuccess('Post saved.');
}

}


Finally - the PostCreateRequest class:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Carbon\Carbon;

class PostCreateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize()
{
return true;
}

/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'title' => 'required',
'subtitle' => 'required',
'content' => 'required',
'publish_date' => 'required',
'publish_time' => 'required',
'layout' => 'required',
];
}

/**
* Return the fields and values to create a new post from
*/
public function postFillData()
{
$published_at = new Carbon(
$this->publish_date.' '.$this->publish_time
);
return [
'title' => $this->title,
'subtitle' => $this->subtitle,
'page_image' => $this->page_image,
'content_raw' => $this->get('content'),
'meta_description' => $this->meta_description,
'is_draft' => (bool)$this->is_draft,
'published_at' => $published_at,
'layout' => $this->layout,
];
}
}


Checking the route list with Artisan returns the following:

POST | admin/post | post.store | App\Http\Controllers\Admin\PostController@store | web,auth

GET|HEAD | admin/post | post.index | App\Http\Controllers\Admin\PostController@index | web,auth |

GET|HEAD | admin/post/create | post.create | App\Http\Controllers\Admin\PostController@create | web,auth |

PUT|PATCH | admin/post/{post} | post.update | App\Http\Controllers\Admin\PostController@update | web,auth |

DELETE | admin/post/{post} | post.destroy | App\Http\Controllers\Admin\PostController@destroy


What I don't understand about this is why the other objects seem to be working under the exact same conditions. There is a small different in how the form post is being done, that I assume is causing the issue. I feel like there is something else that needs to be configured or "connected" to make sure the {{ route()}} call finds the correct url.

Any help is greatly apprecited.

Answer

By looking your route list it is confirmed that there is no route named admin.post.store which you were using in your form.

So to solve this you can change the names of resource routes.

Example from docs:

Route::resource('photo', 'PhotoController', ['names' => [
    'create' => 'photo.build'
]]);

So in your case, it will be as:

Route::resource('admin/post', 'PostController', ['except' => 'show', 'names' => [
    'store' => 'admin.post.store'
]]);

Like this, you can define more names to the routes.

Update

Route::group(['prefix' => 'admin', 'as' => 'admin.'], function () {
    Route::resource('post', 'PostController', ['except' => 'show']);
});