Probably you just need to specify the model like this
public function create(Category $category)
{
return view('articles.create')
->with('category', $category);
}
Hi, I'm having, probably a basic issue for some, problems with my edit crud.
I have this two routes in my web.php.
// Categories
Route::resource('docs', 'CategoryController');
// Articles
Route::resource('docs/{category}/', 'ArticleController');
The categories rout generates the url docs/category_name, by having it I can create categories in separate table.
The second route is for creating articles. I'd like to display it like docs/category_name/article_name.
But then I get the error "Missing required parameters for [Route: store] [URI: docs/{category}]"
This is my edit crud:
public function create($category)
{
return view('articles.create')
->with('category', $category);
}
Still does it not work.
In my articles.edit file I have the following:
{!! Form::open(['route' => 'store']) !!}
I can't find where I'm wrong. Please provide me with some valuable information. Thank you!
Probably you just need to specify the model like this
public function create(Category $category)
{
return view('articles.create')
->with('category', $category);
}
I did specify the Model, but then "Sorry, the page you are looking for could not be found.". And I am still stuck.
the first parameter of Route::resource is the name of the resource, not the url. Try this:
Route::resource('categories', 'CategoriesController');
Route::resource('articles', 'ArticlesController');
then you'll be able to access the routes using the names:
route('articles.show', $article);
...
route('categories.create');
Yes, but to get the url like I listed above, do I need to use a separate Route:get?
The answer @arukomp gave you is perfect, I didn't pick up on that error. I have a feeling you should not be using resource at all, at least until you get used to how they work. You will have more control if you just write one get() method for each route you want.
You cannot have the two routes as you have shown
// Categories
Route::resource('docs', 'CategoryController');
// Articles
Route::resource('docs/{category}/', 'ArticleController');
because the router cannot differentiate between docs/23 and docs/puppies
All your requests will go to the Category controller and not the to Article.
If you want to use Route::resource then you have to recognise that Article and Category are different resources and should have their own URLs
Okay, I understand. So in short, Route::resource gives the curds it's own URLs. So If I want it to be like a did it above I'll be needing to use Route::get except for put and delete?
@dsml you can type
php artisan route:list
in the console and see all of the routes in your app. This might help you understand what the resource routes are creating for you.
You would see the problem more clearly if you listed the routes out, but you would possibly still need to change the url schema
docs/23 to show document 23docs/puppies to show category 'puppies'cannot co-exist
docs/category/puppies
docs/23
can co-exist if they are in that order since category is matched before trying the variable route with the document ID
Yes, I see. So how can I sort my articles by category and link them like docs/main/some_article_name?
I already applied some hasToMany and BelongsTo in both Models.
What data you return has little to do with the URL
You can pretend to use the category
Route::get('/docs/{category/{slug}','ArticleController@show');
and then in the controller
public function show($category, $slug)
{
$article = Article::where('slug',$slug)->first();
and then never use the category if you have unique slugs for the articles.
So this two can't co-exist. That's now pretty clear. But if I create a PagesController and make a page called docs, can I then somehow get the collection of all categories and articles there or do I need I helper function for that? Thank you!
Your route calls a controller method.
The method gets the data it needs and passes it to the view
You return the view.
Your controller can get data from any of your models and pass as many variables to the view as required.
I did everything you suggested. I have now to separate controllers for the articles and categories. I'll make them only accessible for admin. Then I have the PageController for the other stuff, but because I use slug for both of the categories and the articles if I want to say docs/{slug}/{slug} I then get the error "Route pattern "/docs/{slug}/{slug}" cannot reference variable name "slug" more than once." Is there a way around? I'm using laravel-sluggable by spatie. Thank you!
use something other than slug
I used this Route::get('/docs/{cat}/{slug}', 'PageController@article')->name('article');, where I only get the collection of the categories/the articles by category, but not the article itself. I'm getting "Sorry, the page you are looking for could not be found."
What URL did you use to get page not found?
You are only giving half of the information all the time.
I'm using docs/ for the collection of the categories, then docs/category_name/ for the collection of the articles per category and last docs/category_name/article_name for the article itself.
Routes I'm using:
Route::get('/docs', 'PageController@categories')->name('categories');
Route::get('/docs/{cat}', 'PageController@category')->name('category');
Route::get('/docs/{cat}/{slug}', 'PageController@article')->name('article');
PageController:
/**
* @return \Illuminate\Http\Response
*/
public function categories()
{
$categories = Category::query()->get();
return view('pages.categories.categories')
->with('categories', $categories);
}
/**
* @return \Illuminate\Http\Response
*/
public function category($slug)
{
$category = Category::whereSlug($slug)
->firstOrFail();
return view('pages.categories.category')
->with('category', $category);
}
/**
* @return \Illuminate\Http\Response
*/
public function article($slug)
{
$article = Article::whereSlug($slug)
->firstOrFail();
return view('pages.articles.article')
->with('article', $article);
}
What URL did you use to get page not found?
/**
* @return \Illuminate\Http\Response
*/
public function category($slug)
{
$category = Category::whereSlug($slug)
->firstOrFail();
return view('pages.categories.category')
->with('category', $category);
}
This should be accepting $cat not $slug
What do you mean "What URL did you use to get page not found?". I already gave u the url. It was docs/category/name. The docs and category are working fine, when I come to name it shows me that the page was not found. For linking to the page I have this:
{{ route('article', [$category->slug, $article->slug]) }}.
You have not mentioned the URL - only the route
So, when you get page not found, the address bar says http://yourhost.dev/docs/category/name and you have an article in the database with a slug of name ?
->firstOrFail(); will return 404 if you have no article matching name
Yes I skipped the HTTP part. I know what ->firstOrFail(); does and there is a slug with the article name I try to access. I think the problem lies here: Route::get('/docs/{cat}/{slug}', 'PageController@article')->name('article');.
If I revers the link like {{ route('article', [$article->slug, $category->slug]) }}, article first and then the category, I can access both the category and the article. Only then I get http://yourhost.dev/docs/name/category.
Well I can't really help I'm afraid because you seem incapable of comparing what is in the address bar with the name of the article.
If you don't want to share then fine.
Here's a tip for free
{{ route('article', ['slug'=>$article->slug, 'cat'=>$category->slug]) }}
What do I have to share? I showed you my code.
P.S. I solve my problem. I didn't have to provide the slug param on the article method, as I was just showing a particular article. Everything works fine now. Although I may switch to ASP.NET Core 2 just because my limited knowledge of Laravel.
I ran into the same problem and what I had to do is put the Route::get before the Route::resource like this...
Route::get('/home', 'HomeController@index')->name('home');
Route::get('customers/archived', 'CustomerController@archived')->middleware('auth');
Route::get('customers/undelete/{id}', 'CustomerController@undelete')->middleware('auth');
Route::resource('customers', 'CustomerController')->middleware('auth');
Please or to participate in this conversation.