Route model binding with relationship in laravel - laravel

PUT|PATCH api/v1/tweets/{tweet}/comments/{comment} tweets.comments.update › Api\\V1\\TweetCommentController#update
i've this above route, and i'm trying to bind the relationship from controller
I'm passing formadata with key comment = This is a test comment
I tried this code below in TweetCommentController.
public function update(Tweet $tweet, TweetComment $comment, TweetCommentRequest $request)
but this is not working. it just redirect to the login page.
I also tried this below too
public function update(Tweet $tweet, TweetComment $comment)
This one seems working, atleast i'm able to log $tweet and $comment., but i cannot access the form data.
Please help.

My mistake,
I tried the api call from postman, and i used method PUT.
I changed the method to POST and add a new key _method = PUT in form data
so, my current (working) code looks like this
API call
POST {{base_url}}/tweets/1/comments/2
form-data :
comment = "edited test comment"
_method = PUT
Controller
public function update(TweetCommentRequest $request, Tweet $tweet, TweetComment $comment){
$comment->update($request->validated());
return $this->sendResponse([
'message' => __('Comment updated successfully.'),
'comment' => $comment
]);
}

Related

Why this Implicit Binding is not working? - Laravel

I'm using Laravel 9. I have a problem, i wil appreciate any help.
I Have a Model named Entity, a controller EntityControler, and a FormRequest UpdateEntityRequest.
My API Routes looks like:
Route::apiResource('entities', EntityController::class);
so i have show, create, store, update, delete... routes.
This is muy update method in EntityController (without the code/not important now)
public function update(UpdateEntityRequest $request, Entity $entity)
{
return $entity;
}
the update method works perfect. But I want another update method for only a section and here starts the problem.
This is my new API Routes:
Route::apiResource('entities', EntityController::class);
Route::patch('/entities/{id}/{section}',[EntityController::class, 'updateSection' ]);
And this is the new method in the controller(without code yet):
public function updateSection( UpdateEntityRequest $request,Entity $entity, $section)
{
return $entity;
}
But this last method return [] insted of the Entity and the update method works. WHY?
I change de uri in Postman for update PUT {{baseUrl}}/entities/1 and for updateSection {{baseUrl}}/entities/1/1 .
Why does work in update and not in updateSection?
PD:
This method work, and give the id, and I can create a Entity from this:
public function updateSection( UpdateEntityRequest $request, $entity, $section)
{
return $entity;
}
But this is not what I want. Any idea why this happen?
please make sure your uri segment is same as the variable name in the controller, in your case replace id with entity
Route::patch('/entities/{entity}/{section}',[EntityController::class, 'updateSection' ]);
for more please see documentation
Make the route param name consistent in your route api.php and your function updateSection in EntityController
Route::patch('/entities/{entity}/{section}',[EntityController::class, 'updateSection' ]);
and
public function updateSection( UpdateEntityRequest $request,Entity $entity, $section)
{
return $entity;
}

Laravel API routes and Controller variable

I'm a new user of Laravel, and i'm a bit confused with Laravel route API and the name of variable in the controller.
Here an example to explain :
An API route
Route::middleware('auth:sanctum')->group( function () {
Route::resource('cepage', CepageController::class);
});
For a PUT or PATCH, i have this function in the CepageController :
public function update(Request $request, Cepage $cepage)
{
$input = $request->all();
$validator = Validator::make($input, [
'libelle' => 'required',
'abrege' => 'required'
]);
if($validator->fails()){
return $this->sendError($validator->errors());
}
$cepage->libelle = $input['libelle'];
$cepage->abrege = $input['abrege'];
$cepage->save();
return $this->sendResponse(new CepageResource($cepage), 'Cépage mis à jour');
}
If you see my route name "cepage" have the same name of the $cepage variable of the function declaration in the controller, Laravel update the record in the database.
If they are no identical, Laravel create a new record in the database.
Why they need to be exactly the same ?
I think i miss something in the documenation of Laravel.
Thanks for your explanations.
It needs to be the same, for laravel to know what object does he needs to create for us.
Route::resource does a few routes for you, with the base url give into it (https://laravel.com/docs/8.x/controllers#actions-handled-by-resource-controller)
So once you have defined Route::resource('cepage', CepageController::class)
You will have the following routes defined:
Verb URI Action Route Name
GET /cepage CepageController#index cepage.index
GET /cepage/create CepageController#create cepage.create
POST /cepage CepageController#store cepage.store
GET /cepage/{cepage_id} CepageController#show cepage.show
GET /cepage/{cepage_id}/edit CepageController#edit cepage.edit
PUT/PATCH /cepage/{cepage_id} CepageController#update cepage.update
DELETE /cepage/{cepage_id} CepageController#destroy cepage.destroy
And in the controller you need to follow the naming, because in the url you have only ids of the object. But if you follow the naming, laravel will fetch the object for you by its id. See:
public function update(Request $request, $cepage_id)
{
$cepage = Cepage::find($cepage_id);
//here you have to fetch the object for yourself to access it
}
public function update(Request $request, Cepage $cepage)
{
//here you can already access $cepage variable
}

Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException The POST method is not supported for this route. Supported methods: GET, HEAD

these are my codes for route and controller
routes:
Route::get('/form/create','MyformController#create')->name('form');
Route::post('form', 'MyformController#store');
controller:
public function create()
{
return view('formsubmitted');
//i have put form.create as shown in a laravel tutorial
//but it was showing an error that view form.create is not found, hence i
//changed it to formsubmitted(i created that form)
}
public function store(Request $request)
{
$validateData = $request->validate(
[
'Full Name'=>'required',
'Email'=>'required',
'Feedback'=>'required',
]);
form::create($request->all());
}
I am new to laravel and doing the task of creating a feedback form and storing user info and answer to a database.
I hope to hear from you guys soon. Thank you
/form/create/ and form are two different routes. If you want the same route for the GET and POST function, the routes have to be the same.
Route::get('/form/create','MyformController#create')->name('form');
Route::post('/form/create', 'MyformController#store');
If it is rest api then it might me authentication issue
goto VerifyCsrfToken.php and add there your url for eception
for eg.
protected $except = [
'/anyotherurl',
'/api/userlist'
];

PUT in laravel API

I'm studying api rest with laravel, I was able to implement all methods except PUT. Although the routes and controllers are correctly configured a response to a request using the PUT method is "laravel put Sorry, the page you are looking for could not be found.", As now image.
here is the method code in the controller in app/Http/Controllers/LivroController.php:
public function store(Request $request) {
$livro = $request->isMethod('put') ? Livro::findOrFail($request->livro_id) : new Livro;
$livro->id = $request->input('livro_id');
$livro->nome = $request->input('nome');
$livro->descricao = $request->input('descricao');
$livro->user_id = 1; //$request->user()->id;
if($livro->save()) {
return new LivroResource($livro);
}}
here is the route code in /routes/api.php:
Route::put('livro', 'LivroController#store');
change your postman method to POST and then add new parameter in your Body :
"_method" : PUT
This is because HTML forms do not support PUT, PATCH or DELETE actions. So, when defining PUT, PATCH or DELETE routes that are called from an HTML form, you will need to add a hidden _method field to the form
If you want to create new data, you should use post method,
Route::post('livro', 'LivroController#store');
public function store(Request $request) {
If you want to update exist data you should use put method,
Route::put('livro/{id}', 'LivroController#update');
public function update(Request $request, $id) {
You can use this package https://github.com/durmus-aydogdu/laravel-resource for rest calls. This package highly customizable for rest and resource calls.
Is better that you use controllers type resources and for this case the put method. Also you should validate the request. For example:
public function update(Request $request, $id)
{
$livro = Livro::findOrFail($id);
$validator = Validator::make($request->all(), [
'livro_id' => 'required',
'nome' => 'required',
'descricao' => 'required',
]);
if ($validator->fails()) {
return response()->json(['errors'=>$validator->messages()],Response::HTTP_UNPROCESSABLE_ENTITY);
}else{
$livo->update($request->all());
return response()->json(['livro'=>$livro], Response::HTTP_OK);
}
}

How to pass id from (form) of view blade to route (web.php) :Route

I need to pass an id to the route (web.php) from the form. My application has comment section at opporunities/id (id in value) , Whenever non-Auth user submits comment , my app will ask login and redirects to /opportunities but i need /opportunities/id. In the form of comment i have submitted page id. I have setup my route as
Route::post('/opportunities', 'OpportunitiesController#postPost')->name('posts.post'); Now if i can pass that id to as /opportunities/id then after login user will automatically lands on that page. I have manually tested and attached id and it works. Do I need to use "use Illuminate\Http\Request;" to get form data to web.php (route)? to get request post id? All i need is to add id after Route:post('/opportunites/'). Any suggestion and help will be appropriated.
What I did was and figured out is that
action="{{route('opportunities',['returnvalue'=> $post['id']]) }}" I still got error #bipin answer but i passed it with as parameter and solved. Thanks bipin for suggestion though!
One solution could be, pass your post id inside the form
View Blade
{{ Form::hidden('post_id', 'value', array('id' => 'post_id')) }}
Controler
use Illuminate\Http\Request;
public function comment(Request $request)
{
//Validation
$this->validate($request, [
'post_id' => 'required'
]);
//Inside variable
$input = $request->all();
// OR
$request->post_id;
}

Resources