Custom PUT route with FormRequest in Laravel - laravel

I want to make a custom PUT route to manage AJAX request
Route::post('some/{id}/another/new', 'SomeController#store');
Route::put('some/{cid}/another/{id}/edit', 'SomeController#update');
and I want to use FormRequest as a request parameter
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(DirectionRequest $request)
{
$data = $request->validated();
$direction = Direction::create($data);
return response()->json($direction, 201);
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param \App\Direction $direction
* #return \Illuminate\Http\Response
*/
public function update(DirectionRequest $request, $clientId, $directionId )
{
$data = $request->validated();
$direction = Direction::find($directionId);
$direction->update($data);
return response()->json($direction, 201);
}
DirectionRequest.php
<?php
namespace App\Http\Requests;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class DirectionRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'country' => 'required|string|max:255'
];
}
/**
*
* #return type
*/
public function all($keys = null) {
$data = parent::all();
$data['created_by'] = Auth::User()->id;
return $data;
}
/**
*
* #param Validator $validator
* #throws HttpResponseException
*/
protected function failedValidation(Validator $validator) {
throw new HttpResponseException(response()->json($validator->errors(), 422));
}
}
and AJAX call
const editData = new FormData();
editData.append("country", document.getElementById('country').value);
return fetch(`/some/` + sidId + `/another/` + id + `/edit`, {
method: "PUT",
body: editData,
headers: new Headers({
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
})
})
.then(response => {
if (!response.ok) {
throw new Error(response.statusText)
}
return response.json()
})
.catch(error => {
console.log(error)
});
And I get 422 Unprocessible Entity error which return all my model fields with errrors, but they are filled and sended by the AJAX request.
How to use FormRequest in custom route to use validation rules from it? I dont want to copy code with rules because I use that FormRequest in another method (store) and there it works
Simple Request shows put data, but FormRequest doesn't

After follow #RossWilson link
laracast.com I've change my request type to POST and then I could validate inputs with FormRequest rules and other stuff from it

Related

Laravel: resolveRouteBinding() Issue

I having a difficulty displaying my edit view. Displaying all event and creating an event seems to work fine. I even added my own custom resolveRouteBinding method to troubleshoot where the problem is, but it doesn't seem to work every time I hit the url on the browser.
This is the a part of the Event model
class Event extends Model
{
use HasAddress, HasTestData, SoftDeletes;
/**
* Retrieve the model for a bound value.
*
* #param mixed $value
* #param string|null $field
* #return \Illuminate\Database\Eloquent\Model|null
*/
public function resolveRouteBinding($value, $field = null)
{
return $this->find(1)->firstOrFail();
//abort(404);
}
}
This is the event part of the routes:
Route::resource('events', 'EventController')->only(['store', 'update','destroy']);
Route::prefix("events")->name("events.")->middleware("can:viewAny,App\Models\Event")->group(function() {
Route::get("/", function(){
return redirect("admin/events/overview");
});
Route::view("overview", 'admin.events.overview')->name('overview');
Route::view("manage", "admin.events.manage")->name("manage");
Route::view("create", "admin.events.create")->middleware("can:create,App\Models\Event")->name("create");
Route::get("{event}", function (App\Models\Event $event) {
return view("admin.events.view", ["event" => $event]);
})->middleware("can:view, event")->name("view");
Route::get("{event}/edit", function (App\Models\Event $event) {
return view("admin.events.edit", ["event" => $event]);
})->middleware("can:update, event")->name("edit");
});
While this is a part of the EventController
<?php
namespace App\Http\Controllers;
use App\Models\Event;
class EventController extends Controller {
/**
* Show the form for editing the specified resource.
*
* #param \App\Models\Event $event
* #return \Illuminate\Http\Response
*/
public function edit(Event $event){
$this->authorize('update', $event);
return view('admin.events.edit', ['event' => $event]);
}
}

Trying to get property of non-object. Error in laravel

I'm kinda new at laravel and need your help.
I have this IR model :
class IR extends Model
{
//
protected $fillable=['irnum','date','subject','cause','facts','as','at','rec','user_id'];
protected $casts=['user_id'=>'int'];
public function user()
{
return $this->belongsTo(user::class);
}
public static $rules =array (
'date'=>'required',
'status'=>'required|min:10',
'cause' => 'required|min:10',
'facts' => 'required|min:10',
'ir-as' => 'required|min:10',
'rec' => 'required|min:10',
'ir-at' => 'required|min:10',
);
}
and route:
Route::group(['middleware' => ['web']], function () {
Route::get('/', function () {
return view('welcome');
})->middleware('guest');
Route::resource('tasks','TaskController');
Route::get('ir',function ()
{
return View::make('tasks/ir');
});
Route::resource('irs','IRController');
Route::auth();
});
and this is my controller :
class IRController extends Controller
{
/**
* The task repository instance.
*
* #var TaskRepository
*/
protected $irs;
/**
* Create a new controller instance.
*
* #param TaskRepository $tasks
* #return void
*/
public function __construct(IRRepository $irs)
{
$this->middleware('auth');
$this->irs = $irs;
}
/**
* Display a list of all of the user's task.
*
* #param Request $request
* #return Response
*/
public function index(Request $request)
{
return view('tasks.ir',[
'irs' => $this->irs->forUser($request->user()),
]);
}
/**
* Create a new task.
*
* #param Request $request
* #return Response
*/
public function create()
{
return View::make('irs.create');
}
public function store(Request $request)
{
$request->user_id=Auth::user()->id;
$input =$request->all();
$validation=Validator::make($input, IR::$rules);
if($validation->passes())
{
IR::create($input);
return Redirect::route('tasks.ir');
}
return Redirect::route('tasks.ir')
->withInput()
->withErrors($validation)
->with('message','There were validation errors.');
}
/**
* Destroy the given task.
*
* #param Request $request
* #param Task $task
* #return Response
*/
public function destroy(Request $request, IR $irs)
{
}
}
I really dont know what causes to throw this error.
Error throws when i add Incident report.
Pls help.
New at laravel
You're saying you get an error when you're trying to add an incident report or IR, so I assume problem is in a store() action.
I can see only one potential candidate for this error in a store() action:
Auth::user()->id;
Add dd(Auth::user()); before this clause and if it will output null, use check() method, which checks if any user is authenticated:
if (Auth::check()) {
Auth::user->id;
}

ErrorException in SessionGuard.php | Getting error when trying to register user while creating new order

I want user to register and also buy a package. To do that I took input for registration details and package details. Now when I'm processing order to save package details in session and register, I get this error : Argument 1 passed to Illuminate\Auth\SessionGuard::login() must be an instance of Illuminate\Contracts\Auth\Authenticatable, instance of Illuminate\View\View given, called in C:\xampp\htdocs\rename\app\Traits\OrderRegister.php on line 63 and defined. I'm using an trait to register user and return back to function when registration is complete.
OrderController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Package;
use App\ListingType;
use Illuminate\Support\Facades\Auth;
use App\Order;
use Carbon\Carbon;
use App\Traits\OrderRegister;
class OrderController extends Controller
{
use OrderRegister;
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index($type)
{
$listingtype = ListingType::where('type', '=', $type)->first();
if ($listingtype) {
$packages = $listingtype->packages()->get();
return view('packages.index', compact('packages'));
}
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create($id)
{
$package = Package::where('id', '=', $id)->first();
if (Auth::check()) {
return view('order.create_loggedin', compact('package'));
}
else {
return view('order.create_register', compact('package'));
}
}
/**
* Process a new order request. Store order values in session.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function process(Request $request)
{
$order = ['package_id' => $request->package_id, 'order_qty' => $request->no_of_listing];
session(['order' => $order]);
if (Auth::guest()) {
return $this->register($request); // need to check session for orders available in OrderRegister trait.
}
return $this->store($request);
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
if($request->session()->has('order')) {
$package = Package::where('id', '=', $request->package_id )->first();
if($request->user() == Auth::user()) {
for( $n=1;$n<=$request->no_of_listing;$n++) {
$order = new Order;
$order->package_id = $request->package_id;
$order->user_id = Auth::user()->id;
$order->expire_at = Carbon::now()->modify('+'.$package->duration_in_months.' months');
$order->save();
}
return redirect('/');
}
}
}
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
//
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}
trait : OrderRegister.php
<?php
namespace App\Traits;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Validator;
trait OrderRegister
{
use RedirectsUsers;
/**
* Get a validator for an incoming registration request.
*
* #param array $data
* #return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'username' => 'required|max:255|unique:users',
'password' => 'required|min:6|confirmed',
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return User
*/
protected function create(array $data)
{
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'username' => $data['username'],
'password' => bcrypt($data['password']),
]);
$user->profile()->save(new UserProfile);
return $user;
}
/**
* Execute the job.
*
* #return void
*/
public function register(Request $request)
{
$validator = $this->validator($request->all());
if ($validator->fails()) {
$this->throwValidationException(
$request, $validator
);
}
Auth::guard($this->getGuard())->login($this->create($request->all()));
return $this->store($request);
}
/**
* Get the guard to be used during registration.
*
* #return string|null
*/
protected function getGuard()
{
return property_exists($this, 'guard') ? $this->guard : null;
}
}
I could not find any solution for this error so created my own thread for the first time please someone help.
It throws an error because you are trying to login a vue.
in your OrderController.php you are using create method which return a view.
this method will override the create method on your trait.
So you have something like this :
Auth::guard($this->getGuard())->login(/* A view */);
you can at least rename the method on the trait from create to createUser for example.
then you call it from the guard like this :
Auth::guard($this->getGuard())->login($this->createUser($request->all()));

Form request not working for controllers within subfolder of Controller folder

My folder structure for controllers is:
and I use following route code to access those controllers.
here I have allocated sub-folders inside Controller folder and updated namespaces as per needed on files and routes accordingly, this works perfectly, however when I use request file for validating form. It gives error:
Argument 1 passed to App\Http\Controllers\site\usersController::store()
must be an instance of Illuminate\Http\Request, string given
but when I move all controllers file to Controller folder and don't use sub-folder,form request validation works.My usersController and UserRegReq request files are:
usersController.php
<?php
namespace App\Http\Controllers\zcms;
use Illuminate\Http\Request;
use App\Services\FieldService;
use App\Services\UserService;
use App\Http\Requests;
use App\Http\Requests\UserRegReq;
use App\Http\Controllers\Controller;
class usersController extends Controller {
public function __construct(FieldService $field, UserService $user)
{
$this->field = $field;
$this->user = $user;
}
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index()
{
//
}
/**
* Display a listing of the resource.
*
* #return Response
*/
public function throwLogin()
{
return view('zcms.pages.login');
}
/**
* Show the form for creating a new resource.
*
* #return Response
*/
public function create()
{
$field = $this->field->fieldList();
return view('zcms.users.addnew', compact('field'));
}
/**
* Store a newly created resource in storage.
*
* #param Request $request
* #return Response
*/
public function store(UserRegReq $request)
{
return "hello";
}
/**
* Display the specified resource.
*
* #param int $id
* #return Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* #param Request $request
* #param int $id
* #return Response
*/
public function update(Request $request, $id)
{
//
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return Response
*/
public function destroy($id)
{
//
}
}
UserRegReq.php
<?php
namespace App\Http\Requests;
use App\Http\Requests\Request;
class UserRegReq extends Request {
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'field_id' => 'required',
'name' => 'required',
'username' => 'required',
'password' => 'required'
];
}
// public function messages(){
// return [
// 'field_id.required'=>'The related Field of your Job is required',
// ];
// }
}
What should I do beside updating namespace in routes and controller file to make everything work?

Laravel 5.0 | Changing default actions' names is not working for a resource controller

I have created a productController resource in the route.php file like this:-
Route::resource('products','ProductController',['names' => ['create' => 'products.add']]);
Here is how my productController.php file looks like:-
<?php namespace lvtest\Http\Controllers;
use lvtest\Http\Requests;
use lvtest\Product;
use lvtest\Http\Controllers\Controller;
use Illuminate\Http\Request;
class ProductController extends Controller {
/**
* Class constructor .. requires authentication
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index()
{
$products = Product::all();
return view('products.productsList', ['products' => $products]);
}
/**
* Show the form for creating a new resource.
*
* #return Response
*/
public function add()
{
return 'Add a product';
}
/**
* Store a newly created resource in storage.
*
* #return Response
*/
public function store()
{
return 'store new product?';
}
/**
* Display the specified resource.
*
* #param int $id
* #return Response
*/
public function show($id = null)
{
// $products = Product::all();
// print_r($products);
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* #param int $id
* #return Response
*/
public function update($id)
{
return 'store new product?';
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return Response
*/
public function destroy($id)
{
//
}
}
and passed the 'names' array to change the default name of the create method to add.
When I go to localhost:8000/products/add I get a blank page.
How do I fix this
Adding the ['names' => ['create' => 'products.add'] to your resource route will only change the Route Name, and not the Route Method. This means that you can refer to your route as route('products.add') and it will point to the create() method on your controller.
When you use Route::resource Laravel will expect that you have a create() method on your controller. To be able to do what you suggest, you might need to add the method to your controller, and then add a separate route:
Route::resource('products','ProductController');
Route::get('products/add', ['as' => 'products.add', 'uses' => 'ProductController#add']);

Resources