Page you are looking for not found laravel 5.5 - laravel

I am getting the
Sorry, the page you are looking for could not be found.
On Laravel 5.5. I am sure I'm missing something very small. But not sure what it is because I'm a laravel learner. Please see below:
ROUTE
Auth::routes();
Route::get('/curriculum-sections','CurriculumsectionsController#index')->name('curriculum-sections');
Route::resource('/curriculum-sections','CurriculumsectionsController');
CONTROLLER
public function show(Curriculumsection $curriculumsection)
{
//
$curriculum = Curriculum::findOrFail($curriculumsection->id);
return view('curriculum-sections.show', ['curriculum'=>$curriculum]);
}
and I also made sure that the page exists in the views folder. While troubleshooting I also did php artisan route:list and this is what I got
Edit:
I am accessing the error from:
http://localhost:8000/curriculum-sections/1

The problem is that your route defines id for model Curriculumsection. You're using model binding, which will automatically query for Curriculumsection::findOrFail(route_id) (in your case route_id is 1). And then you're using the same id to query model Curriculum as well, with ->findOrFail(route_id).
So in order for this route to return anything other than 404, you have to have a record of Curriculumsection with id 1 and a record of Curriculum with id 1 in your database.
I'm not sure how your database is set up, or how these 2 models are related to each other, but definitely not by same id (otherwise, why not have all data in the same table).
Something like this would make more sense (binding the Curriculum model directly):
public function show(Curriculum $curriculum)
{
return view('curriculum-sections.show', ['curriculum'=>$curriculum]);
}
This would bind the Curriculum model to the route and automatically fetch the one with passed in id.
Or something like this for your use case, but it assumes that you have a working relationship called curriculum() on your Curriculumsection model:
public function show(Curriculumsection $curriculumsection)
{
$curriculum = $curriculumsection->curriculum;
return view('curriculum-sections.show', ['curriculum'=>$curriculum]);
}

I dont think that you need the first get route. You just define the Route::resource(...) and that's it. Laravel handles the different requests.
See here -> Resource Controllers

Related

Custom Routes not working - 404 not found

I'm trying to create a custom route. The must be in this format: http://localhost:8000/home-back-to-school but instead I get a 404 not found error. http://localhost:8000/posts/home-back-to-school works, but that's not what I'm trying to get working.
My routes on web.php are defined as: Route::resource('posts',PostsController::class);
I modified the Route Service Provider by adding the code below:
parent::boot();
Route::bind('post',function($slug){
return Post::published()->where('slug',$slug)->first();
});
The published scope is defined in the Post Model file(Post.php) as:
public function scopePublished()
{
return $this->where('published_at','<=',today())->orderBy('published_at', 'desc');
}
I've done previously with laravel 5.x, now struggling with laravel 8.x
Link to the Documentation: Laravel 8 Documentation
You should define a custom route since you don't want to use the resourceful route for this method.
In your web.php
// Keep all your resource routes except the 'show' route since you want to customize it
Route::resource('posts', PostsController::class)->except(['show']);
// Define a custom route for the show controller method
Route::get('{slug}', PostsController::class)->name('posts.show');
In your PostController:
public function show(Post $post)
{
return view('posts.show', compact('post'));
}
In your Post model:
// Tell Laravel your model key isn't the default ID anymore since you want to use the slug
public function getRouteKeyName()
{
return 'slug';
}
You may have to fix your other Post routes to make them work with this change since you are now using $post->slug instead of $post->id as the model key.
Read more about customizing the model key:
https://laravel.com/docs/8.x/routing#customizing-the-default-key-name
You should also remove the code you have in the boot method and use the controller instead.
Finally, make sure your post slug is always unique for obvious reason.
Note:
You may run into problems if your other routes are not related to the Post model.
Imagine if you have a route called example.com/contact-us. Laravel has no way to "guess" if this route should be sent to the PostController or the ContactController. contact-us could be a Post slug or it could be a static route to your contact page. That's why it's generally a good idea to start your urls with the model name. In your case, it would be a good idea for your Post route to start with "/posts/" like this: http://example.com/posts/your-post-slug. Otherwise you may run into all sorts unexpected routing issues.
Don't fight the framework: Always follow best practices and naming conventions when you can.

How will I identify resource default url in laravel?

I am running this command for model, migration, resource controller.
`php artisan make:model QuestionAnswer -mc -r` ..
Laravel give me in Resource Controller
public function show(QuestionAnswer $questionAnswer) {
// return $questionAnswer;
}
public function edit(QuestionAnswer $questionAnswer) {
// return $questionAnswer;
}
public function update(Request $request, QuestionAnswer $questionAnswer){
// return $questionAnswer;
}
if I write in web.php
Route::resource('question-answer','QuestionAnswerController'); or
Route::resource('questionAnswer','QuestionAnswerController'); or
Route::resource('question_answer','QuestionAnswerController'); laravel resolve route model binding...
that means....
Example as a
public function edit(QuestionAnswer $questionAnswer)
{
return $questionAnswer;
}
$questionAnswer return object for this url {{route('admin.question-answer.edit',$questionAnswer->id)}}
but if I write in web.php Route::resource('faq','QuestionAnswerController');
laravel can not resolve route model binding...
that means.. $questionAnswer return null for this url {{route('admin.faq.edit',$questionAnswer->id)}}
also in show and update function $questionAnswer; return null...
for working as a faq url.. i need change in edit function variable($faq) . or Route::resource('faq','QuestionAnswerController')->parameters(['faq' => 'questionAnswer']);I
But These three url questionAnswer,question-answer,question_answer by default work...
I check it on "laravel/framework": "^6.0" (LTS)
Question
is there possible way to find out what exact url I will write ? .. like question-answer.. or is there any command line ...
after running auth command .. php artisan route:list command give us all route list.. and when I make model Category laravel create table name categories and follow grammar rules
Actually Laravel has got Naming Convection Rules In its core.
These Convictions make it to default binding database_tables to model, model to controllers ....
if you want, you can tell your custom parameters but if you dont, The Laravel uses its own default and searching for them.
for example: if you have a model named bar, laravel look for a table named plural bars . and if you dont want this behave, you can change this default by overriding the *Models* $table_name` attribute for your custom parameter.
There are some Name Convection Rules Like :
tables are plural and models are singular : its not always adding s (es) in trailing.
sometimes it acts more complicate. like : model:person -> table: people
pivot table name are seperate with underline and should be alphabetic order: pivot between fooes and bars table should be bar_foo (not foo_bar)
table primary key for Eloquent find or other related fucntion suppose to be singular_name_id : for people table : person_id
if there are two-words name in model attribute, all of these are Alias :
oneTwo === one_two == one-two
check this out:
class Example extends Model{
public function getFooBarAttribute(){
return "hello";
}
}
all of this return "hello" :
$example = new Example();
$example->foo_bar();
$example->fooBar();
// $example->foo-bar() is not working because - could be result of lexical minus
there is a page listing laravel naming conventions :
https://webdevetc.com/blog/laravel-naming-conventions/
Name Conventions : is The Language Between The Laravel and Developer
it made it easy to not to explicitly mention everything
like Natural Language we can eliminate when we think its obvious.
or we can mention if its not (like ->parameter(...)).
How will I know I need to write question-answer this ? by default it works... when i write faq i need to change in edit function variable($faq) .
How will I know by default url (question-answer) will work ..when php
artisan route:list command give us all route list.. and when I make
model Category laravel create table name categories and follow grammar
rules
think about i will create 20 model ,migration & controller by cmd... i will not change edit,show and update function variable ...how i will know the default url for 20 model and controller ?
Laravel is an opinionated framework. It follows certain conventions
Let us understand a route parts
Route::match(
['PUT', 'PATCH'],
'/question-answer/{questionAnswer}',
[QuestionAnswerController::class, 'update']
)->name('question-answers.update')
In the above route:
1st argument: ['PUT', 'PATCH'] are the methods which the route will try to match for an incoming request
2nd argument: '/question-answer/{questionAnswer}' is the url wherein
/question-answer is say the resource name and
{questionAnswer} is the route parameter name
3rd argument: [QuestionAnswerController::class, 'update'] is the controller and the action/method which will be responsible to handle the request and provide a response
When you create a model via terminal using
php artisan make:model QuestionAnswer -mc -r
It will create a resource controller for the 7 restful actions and take the method parameter name for show, edit, update and delete routes as camel case of the model name i.e. $questionAnswer
class QuestionAnswerController extends Controller
{
public function show(QuestionAnswer $questionAnswer){}
public function edit(QuestionAnswer $questionAnswer){}
public function update(Request $request, QuestionAnswer $questionAnswer){}
public function delete(QuestionAnswer $questionAnswer){}
}
Which means if you don't intend to change the parameter name in the controller methods then you can define the routes as below to get the benefit of implicit route model binding
//Will generate routes with resource name as questionAnswer
//It would not be considered a good practice
Route::resource('questionAnswer', QuestionAnswerController::class);
//OR
Route::resource('question-answer', QuestionAnswerController::class)->parameters([
'question-answer' => 'questionAnswer'
]);
//OR
Route::resource('foo-bar', QuestionAnswerController::class)->parameters([
'foo-bar' => 'questionAnswer'
]);
RFC 3986 defines URLs as case-sensitive for different parts of the URL. Since URLs are case sensitive, keeping it low-key (lower cased) is always safe and considered a good standard.
As you can see, you can name the url resource anything like foo-bar or question-answer instead of questionAnswer and yet keep the route parameter name as questionAnswer to match the Laravel convention when generating controller via php artisan make:model QuestionAnswer -mc -r and without having to change the parameter name in controller methods.
Laravel is an opinionated framework which follows certain conventions:
Route parameter name ('questionAnswer') must match the parameter name in controller methods ($questionAnswer) for implicit route model binding to work
Controller generated via artisan commands, have parameter name as camelCase of the model name
Routes generated via Route::resource('posts', PostController::class) creates routes with resource name equal to the first argument of the method and route parameter name as the singular of the first argument
Route::resource() provides flexibility to use a different name for route resource name and route parameter name
Read more at Laravel docs:
https://laravel.com/docs/8.x/controllers#restful-naming-resource-route-parameters
https://laravel.com/docs/8.x/controllers
https://laravel.com/docs/8.x/routing#route-model-binding
If you want to know how the php artisan make:model works you can study the code in vendor/laravel/framework/src/Illuminate/Foundation/Console/ModelMakeCommand.php and have a look at the various stubs these commands use to generate the files.
For almost all artisan commands you will find the class files with code in
vendor/laravel/framework/src/Illuminate/Foundation/Console and the stubs used by the commands to generate files in vendor/laravel/framework/src/Illuminate/Foundation/Console/stubs folder.
If you study these command classes properly then you will get an idea of the various conventions Laravel follows when generating files via the artisan commands
I think its becuse of dependency injection which you used in youre method.
Try this
public function edit($id)
{
// return $questionAnswer;
return view('backend.faq.edit',get_defined_vars());
}

Laravel route difference between {id} vs {tag}

I am new in Laravel pardon me if question is silly. I have seen a doc where they used
For get request
Route::get("tags/{id}","TagsController#show");
For put request
Route::put("tags/{tag}","TagsController#update");
What is the difference and benefit between this ? I understood 1st one, confusion on put route.
There’s no real difference as it’s just a parameter name, but you’d need some way to differential parameters if you had more than one in a route, i.e. a nested resource controller:
Route::get('articles/{article}/comments/{comment}', 'ArticleCommentController#show');
Obviously you couldn’t use just {id} for both the article and comment parameters. For this reason, it’s best to use the “slug” version of a model for a parameter name, even if there’s just one in your route:
Route::get('articles/{article}', 'ArticleController#show');
You can also use route model binding. If you add a type-hint to your controller action for the parameter name, Laravel will attempt to look up an instance of the given class with the primary key in the URL.
Given the route in the second code example, if you had a controller that looked like this…
class ArticleController extends Controller
{
public function show(Article $article)
{
//
}
}
…and you requested /articles/123, then Laravel would attempt to look for an Article instance with the primary key of 123.
Route model binding is great as it removes a lot of find / findOrFail method calls in your controller. In most instances, you can reduce your controller actions to be one-liners:
class ArticleController extends Controller
{
public function show(Article $article)
{
return view('article.show', compact('article'));
}
}
Generally there's no practical difference unless you define a custom binding for a route parameter. Typically these bindings are defined in RouteServiceProvider as shown in the example in the docs
public function boot()
{
parent::boot();
Route::model('tag', App\Tag::class);
}
When you bind tag this way then your controller action can use the variable via model resultion:
public function update(Tag $tag) {
// $tag is resolved based on the identifier passed in the url
}
Usually models are automatically bound so doing it manually doesn't really need to be done however you can customise resolution logic if you do it manually
Normal way
Route::get("tags/{id}","TagsController#show");
function($id)
{
$tag = Tag::find($id);
dd($tag); // tag
}
With route model bindings
Route::put("tags/{tag}","TagsController#update");
function(Tag $tag) // Tag model binding
{
dd($tag); // tags
}
ref link https://laravel.com/docs/5.8/routing#implicit-binding
It's just a convention. You can call it all you want. Usually, and {id} refers to the id in your table. A tag, or similarly, a slug, is a string value. A tag could be 'entertainment' for video categories, while 'my-trip-to-spain' is a slug for the description of a video.
You have to chose the words what you are comfortable with. The value will be used to find in your database what record is needed to show the correct request in the view. Likewise you can use video/view/{id}/{slug} or any combination thereof.
Just make sure your URLs don't get too long. Because search engines won't show your website nicely in search results if you do. Find the balance between the unambiguous (for your database) and logic (for your visitors).
Check this out: Route model bindings
Use id, Laravel will get the id from route, and it will be the tag's id, it is integer.
function show($id) {
$tag = Tag::find($id);
}
Use tag, Laravel automatically resolves Eloquent models defined in routes or controller actions whose type-hinted variable names match a route segment name.
In URL, your tag parameter is integer, however in your controller action $tag will be a model object:
function action(Tag $tag) {
$tag->name;
}
So you don't need to get the $tag by eloquent in your controller action. You just need to specify it is From model Tag $tag
It will do it automatically.

Want to show name instead of id in the URL field in Laravel

I don't want to show /route_name/{id} in the URL field of my Laravel project. Instead of that I want to show /route_name/{name} but pass the id in the back-end to the controller.
Suppose I have a route named departments and pass an id 3 named knee_pain as a parameter. And it is like /departments/3
But I want to to show /departments/knee_pain in my url and as well as want to pass the id 3 in my controller without showing the id in the url.
How to do that ?
In your model you can use the getRouteKeyName method to bind to another attribute than the default id in your routes :
public function getRouteKeyName()
{
return 'slug'; // Default is 'id'.
}
Rather than using the name attribute, that you could use elsewhere in your application for displaying the name of the entry, I recommend using an attribute made url friendly. You could use Str::slug() for that.
public function setNameAttribute($value) {
$this->name = $value;
$this->slug = \Str::slug($value);
}
It will 'slugify' your string, for example : \Str::slug('Knee pain') => 'knee-pain'.
Note : in Laravel 5.5, use the str_slug() helper.
You should also make sure this string is unique in your database.
First you have to garantee that the name is unique, if don't you will have more than one Id in your controller. For that i recommend you to use Purifier to remove spaces and make it URL friendly:
Purifier
Second, probably the best way to have clean controllers is creating a middleware that understand what kind of name is (what table should middleware look for). You can validate that by route name and send the correct id to controller.
Middleware docs

How do I pass data from my controller to a view in Laravel 5.5?

I have a function that I'm trying to pass some data to a view. I can't get the Route to recognize the data, it just keeps saying my variables are undefined. Here's what I'm trying to do:
return redirect('confirm')->with([
'name'=>$name,
'service'=>$service,
'$email_address'=>$email_address
]);
Then in my web.php file, I have:
Route::get ('confirm', function($name,$service,$email_address){
return view('confirm',compact('name','service','email_address'));
})->name('confirm');
Laravel just throws an error "Missing argument 1 for Illuminate\Routing\Router::{closure}()"
I'm at a complete loss, I've tried this a bunch of different ways. If I call the view right from my controller, it works fine, but then URL isn't what I want it to be, so it seems like I have to return the redirect and reference the data in my route definition. Can anyone enlighten me?
If it's ok to show the email in the route then you can correct the problem like this :
Route::get ('confirm/{name}/{service}/{email_address}', function($name,$service,$email_address){
return view('confirm',compact('name','service','email_address'));
})->name('confirm');
And in the controller :
return \Redirect::route('confirm', [
'name'=>$name,
'service'=>$service,
'email_address'=>$email_address
]);
Ps : this is not recommended i just answer you problem but there is a better way to do it, passing just an id for exsample then find the user by id then take his email and other stuff.

Resources