Laravel Editing post doesn't work - laravel

There are routes
Route::get('posts', 'PostsController#index');
Route::get('posts/create', 'PostsController#create');
Route::get('posts/{id}', 'PostsController#show')->name('posts.show');
Route::get('get-random-post', 'PostsController#getRandomPost');
Route::post('posts', 'PostsController#store');
Route::post('publish', 'PostsController#publish');
Route::post('unpublish', 'PostsController#unpublish');
Route::post('delete', 'PostsController#delete');
Route::post('restore', 'PostsController#restore');
Route::post('change-rating', 'PostsController#changeRating');
Route::get('dashboard/posts/{id}/edit', 'PostsController#edit');
Route::put('dashboard/posts/{id}', 'PostsController#update');
Route::get('dashboard', 'DashboardController#index');
Route::get('dashboard/posts/{id}', 'DashboardController#show')->name('dashboard.show');
Route::get('dashboard/published', 'DashboardController#published');
Route::get('dashboard/deleted', 'DashboardController#deleted');
methods in PostsController
public function edit($id)
{
$post = Post::findOrFail($id);
return view('dashboard.edit', compact('post'));
}
public function update($id, PostRequest $request)
{
$post = Post::findOrFail($id);
$post->update($request->all());
return redirect()->route('dashboard.show', ["id" => $post->id]);
}
but when I change post and click submit button, I get an error
MethodNotAllowedHttpException in RouteCollection.php line 233:
What's wrong? How to fix it?
upd
opening of the form from the view
{!! Form::model($post, ['method'=> 'PATCH', 'action' => ['PostsController#update', $post->id], 'id' => 'edit-post']) !!}
and as result I get
<form method="POST" action="http://mytestsite/dashboard/posts?6" accept-charset="UTF-8" id="edit-post"><input name="_method" type="hidden" value="PATCH"><input name="_token" type="hidden" value="aiDh4YNQfLwB20KknKb0R9LpDFNmArhka0X3kIrb">
but why this action http://mytestsite/dashboard/posts?6 ???

Try to use patch instead of put in your route for updating.
Just a small tip you can save energy and a bit of time by declaring the Model in your parameters like this:
public function update(Post $id, PostRequest $request)
and get rid of this
$post = Post::findOrFail($id);
EDIT
You can use url in your form instead of action :
'url'=> '/mytestsite/dashboard/posts/{{$post->id}}'

Based on the error message, the most probable reason is the mismatch between action and route. Maybe route requires POST method, but the action is GET. Check it.

Try to send post id in hidden input, don't use smt like that 'action' => ['PostsController#update', $post->id]
It contribute to result action url.

Related

Laravel 5.1, passing my ID

I'm trying to pass an ID of a past and insert it into another database.
I got a page with shows posts like this
/posts/{id}
. From there on i want to add a comment section, so i got my form set up like this:
<form method="POST" action="/posts/{{ $post->id }}/comments">
(When i inspect the code, it inserts the right id and the "{{ $posts->id }}" spot.
inside my routes.php i got the folling route:
Route::post('/posts/{post}/comments', 'CommentsController#store');
and inside CommentsController.php i got the following
public function store(Post $post)
{
Comment::create([
'body' => request('body'),
'post_id' => $post->id
]);
return back();
}
When ever i try to add a comment i get this error:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'post_id'
cannot be null
When i change my code from CommentsController.php to this:
'post_id' => "2"
it works fine (but the comment will always be added at post with ID 2)
I can't seem to find out why my id wont go trough.
Anny help with this?
Try this
public function store(Request $request, Post $post)
{
$comment= new Comment;
$comment->body = $request->body;
$comment->post_id = $post->id;
$comment->save();
return back();
}
The route model binding allows you to convert the Post ID passed into the route into the actual post object in the controller method. It may even work smoother if you use a relationship between a post and a comment, like so:
public function store(Request $request, Post $post)
{
$post->comments->create([
'body' => $request->body
]);
return back();
}
Inside post model
public function comments()
{
return $this->hasMany('App\Comment','post_id');
}

Getting errors while submitting the form in laravel 5.5

I am getting either of 2 errors one after the other.
While submitting the form either I get the error below
The page has expired due to inactivity. Please refresh and try again.
Or this error
InvalidArgumentException
Route [register/user/image] not defined.
I have cross checked everything unable to find out the real cause.
Routes/web.php
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::prefix('manage')->middleware('role:superadministrator|administrator|editor|member')->group(function() {
Route::get('/', 'ManageController#index');
Route::get('/carezone', 'ManageController#carezone')->middleware('role:superadministrator|administrator')->name('manage.dashboard');
Route::get('/dashboard', 'ManageController#dashboard')->name('manage.dashboard');
});
Route::middleware('role:superadministrator|administrator|editor|member|subscriber')->group(function() {
Route::get('register/user/details', 'RegisterUserController#showUserDetailsForm')->name('register.user.details');
Route::post('register/user/details', 'RegisterUserController#postUserDetailsForm')->name('register.user.details');
Route::get('/api/username/unique', 'RegisterUserController#apiCheckUniqueUserName')->name('api.username.unique');
Route::get('register/user/image', 'RegisterUserController#showUserImageForm')->name('register.user.image');
Route::post('register/user/image', 'RegisterUserController#postUserImageForm')->name('register.user.image');
});
Route::get('/email/unique', 'RegisterUserController#checkUniqueEmail')->name('email.unique');
Route::get('/get/city', 'RegisterUserController#ajaxGetCity')->name('get.city');
Route::get('/registration', 'RegisterUserController#showRegistrationForm')->name('registration');
Route::get('/home', 'HomeController#index')->name('home');
RegisterUserController.php
/*function to redirect user to user details page after register page*/
public function showUserDetailsForm() {
$states = State::all();
return view('pages.registration.registerUserDetails', ['states'=> $states]);
}
/*function to post and save data to the database*/
public function postUserDetailsForm(Request $request) {
$validatedData = $request->validate([
'username' => 'required|alpha_num|min:6|max:20|unique:details,username',
'dob' => 'required|date',
'gender' => 'required|string',
'state' => 'required|numeric',//validation rule for max min values
'city' => 'required|numeric',//validation rule for max min values
]);
$post = new Detail;
$post->user_id = Auth::user()->id;
$post->username = $request->username;
$post->dob = $request->dob;
$post->gender = $request->gender;
$post->state_id = $request->state;
$post->city_id = $request->city;
$post->save();
return redirect()->route('register/user/image');
}
Small Portion Of my form
<form id="registerUserDetails" class="form-horizontal clearfix" method="POST" action="{{ route('register.user.details') }}" role="form" novalidate>
{{ csrf_field() }}
.
.
.
.
<button type="submit" class="tabButton">Next</button>
</form>
<script>Javascript Validation here</script>
To solve the second error you must fix your route name on your controller method (and everywhere):
Actual:
return redirect()->route('register/user/image');
Correct:
return redirect()->route('register.user.image');
For solving the first error add the csrf field {{ csrf_field() }} to form
And for the second one, you route's name is register.user.image
so set the form's action like this
<form action=" {{ route('register.user.image') }} ">

Laravel error is not passed to view

I can't figure put why laravel blade doesn't catch my error validation and doesn't pass it to my view.
In detail
I do have error snippet in my blade template
below is my validation which works correctly
What I'm missing?
Thank you
This is json message I see instead of message in blade template
{
message: "The given data was invalid.",
status_code: 500
}
This snippet I use to let user know about error
#if(count($errors))
<div class="form-group">
<div class="alert alert-danger">
<ul>
#if($errors->all())
#foreach($errors->all() as $error)
<li>{{$error}}</li>
#endforeach
#endif
</ul>
</div>
</div> #endif
And finally this is my correctly working validation
$request->validate([
'email' => 'required|email|unique:subscribers|max:255',
]);
EDIT:
This is the rout in web.php
Route::post('saveemail', 'SaveSubscriberEmailController#saveEmail');
And this is the method
namespace App\Http\Controllers;
use App\subscriber;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Ramsey\Uuid\Uuid;
class SaveSubscriberEmailController extends Controller
{
public function saveEmail(Request $request)
{
$request->validate([
'email' => 'required|email|unique:subscribers|max:255',
]);
$uuid = Uuid::uuid4();
$subscriber = new subscriber();
$subscriber->email = $request->email;
$subscriber->uuid = $uuid->toString();
$subscriber->created_at = Carbon::now();
$subscriber->save();
flash('Registration conformation email has been sent. Please check your mailbox. Thank you!')->success();
return redirect()->back();
}
}
I've had this problem before and the way I was able to fix it was to wrap the routes with a middleware group that includes the middleware \Illuminate\View\Middleware\ShareErrorsFromSession::class. It adds the session's errors to the view.
In your Kernel.php class's protected $middlewareGroups array it can look something like:
'web' => [
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
// other middleware
],
Then where you declare your routes you can do:
Route::group(['middleware' => ['web']], function () {
Route::post('saveemail', 'SaveSubscriberEmailController#saveEmail');
};
Request validation only send error of 422 not 500 if you are getting this error it's because of something else and the formRequest error bag won't catch this error .
Route::post('saveemail', 'SaveSubscriberEmailController#saveEmail');
Put this route into web middleware. you can do this like
Route::middleware(['web'])->group(function () {
Route::post('saveemail', 'SaveSubscriberEmailController#saveEmail');
});
Change your controller to this.
class SaveSubscriberEmailController extends Controller
{
public function saveEmail(Request $request)
{
$validator = validate($request->all(),[
'email' => 'required|email|unique:subscribers|max:255',
]);
if($validator->fails()){
return back()->withErrors($validator);
}
$uuid = Uuid::uuid4();
$subscriber = new subscriber();
$subscriber->email = $request->email;
$subscriber->uuid = $uuid->toString();
$subscriber->created_at = Carbon::now();
$subscriber->save();
flash('Registration conformation email has been sent. Please check your mailbox. Thank you!')->success();
return redirect()->back();
}
}
Hope this helps

Laravel not reaching update method and returns edit view again – route wrong

When I click Save on my edit view, my routing brings back my edit view instead of my index view and my update method is never reached.
I noticed that I reach the update method if I remove “UsersRequest $request” from the method parameters. Not sure why, and if it’s related, but I need $request to do my update (see controller code below):
Routes:
Route::get('/users', 'UsersController#index')->name('users.index');
Route::patch('/users/{id}',
[
'as' => 'users.update',
'uses' => 'UsersController#update'
]);
Route::get('/users/{id}/edit', 'UsersController#edit');
Controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests\UsersRequest;
//public function update($id, UsersRequest $request)
public function update($id) //- with $request removed, the index view is displayed
{
$user = \Auth::user();
$user->update($request->all());
return view('users.index');
}
Edit view:
{!! Form::model($user, ['method' => 'PATCH', 'action' => [ 'UsersController#update', 'user' => $user->id ] ]) !!}
{!! Form::submit('Save', ['class'=>'btn primary']) !!}
{!! Form::close() !!}
Network after save button clicked
URL Protocol Method Result
/myapp/public/users/1 HTTP POST 302 Goes for the update route
http://000.000.000.000/myapp/public/users/1/edit HTTP POST 200 Redirects to the edit route??
.env
APP_URL=http://000.000.000.000/myapp/public
You're failing whatever validation is present in your UsersRequest form request. When the validation fails, it redirects you back to where you came from, which is your edit view. Your edit view should be updated to show the validation errors so that your users know what fields need to be fixed.
The reason it works when you remove the UsersRequest $request parameter is that the validation is no longer being performed.

Redirect back to same page (with variables) on form submit in Laravel 5

On my page events.index, I first display a list of events for the logged on user.
On my index page I have a form with option/select to let the user select and display the events of another user. When he submits that form, I would like my index function (controller) to use the $user_id value (from the form) and display the events.index page again, but for events of that selected user.
I'm not sure what would be the best approach:
Set a session variable to keep the user_id value? Not sure how to do that with a form.
Submit the form with a get method (and get an ugly ?user_id=1 URL)
Change my index route to accept the post method (although I already have that post/events route taken (by Route::post('events', 'EventsController#store'))
Not sure what would be a clean way to do this:
My route for events/index:
Route::get('events', [
'as' => 'event.index',
'uses' => 'EventsController#index'
]);
Events Controller
public function index()
{
// How to get the $user_id value from form?
if (empty($user_id))
{
$user_id = \Auth::user()->id;
}
$events = Event::where('events.user_id','=','$user_id');
$users = User::all();
return view('events.index')->with(['events' => $events])->with(['users' => $users]);
}
View for index
{!! Form::open(['route' => 'events.index', 'method' => 'get']) !!}
<select id="user_id" name="user_id">
#foreach($users as $user)
<option value="{{$user->id}}">{{$user->name}}</option>
#endforeach
</select>
{!! Form::submit('Show events for this user') !!}
{!! Form::close() !!}
#foreach($events as $event)
...
#endforeach
You can get the user_id from a Request object, you just need to inject it in the index method:
public function index(Request $request)
{
$user_id = $request->get('user_id') ?: Auth::id();
$events = Event::where('events.user_id','=','$user_id')->get();
$users = User::all();
return view('events.index')->with(['events' => $events])->with(['users' => $users]);
}

Resources