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]);
}
}
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I am having this issue when I am trying to make a POST call to a resource. I am striving with this error for hours. Can somebody please help me?
api.php
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::post('login', 'UserController#login')->name('login');
Route::post('register', 'UserController#register')->name('register');
Route::group(['middleware' => 'auth:api'], function(){
Route::post('details', 'UserController#details');
Route::apiResource('schedule', 'ScheduleController');
});
ScheduleController
<?php
namespace App\Http\Controllers;
use App\Schedules;
use App\Http\Resources\Schedule;
use Illuminate\Http\Request;
class ScheduleController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index(){
return Schedule::collection(Schedules::all());
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create(){
//
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Schedule $request)
{
$schedule = new Schedules();
if (isset($request['title'])) {
$schedule->title = $request['title'];
};
if (isset($request['start'])) {
$schedule->start = $request['start'];
};
if (isset($request['end'])) {
$schedule->end = $request['end'];
};
if ($schedule->save()) {
return response()->json(new Schedule($schedule), 200);
} else {
return response()->json('Error can\'t save schedule', 500);
};
}
/**
* Display the specified resource.
*
* #param \App\Schedule $schedule
* #return \Illuminate\Http\Response
*/
public function show(Schedule $id)
{
return response()->json(new Schedule(Schedules::find($id)), 200);
}
/**
* Show the form for editing the specified resource.
*
* #param \App\Schedule $schedule
* #return \Illuminate\Http\Response
*/
public function edit(Schedule $schedule)
{
//
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param \App\Schedule $schedule
* #return \Illuminate\Http\Response
*/
public function update(Request $request, Schedule $schedule)
{
//
}
/**
* Remove the specified resource from storage.
*
* #param \App\Schedule $schedule
* #return \Illuminate\Http\Response
*/
public function destroy(Schedule $id)
{
if (Schedules::find($id)->delete()) {
return response()->json('Success on delete carpet', 200);
} else {
return response()->json('Error can\'t delete carpet', 500);
}
}
public function creazaProgramare(Schedule $request)
{
$schedule = new Schedules();
if (isset($request['title'])) {
$schedule->title = $request['title'];
};
if (isset($request['start'])) {
$schedule->start = $request['start'];
};
if (isset($request['end'])) {
$schedule->end = $request['end'];
};
if ($schedule->save()) {
return response()->json(new Schedule($schedule), 200);
} else {
return response()->json('Error can\'t save schedule', 500);
};
}
}
ScheduleResource
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class Schedule extends JsonResource
{
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return [
'title' => $this->title,
'start' => $this->start,
'end' => $this->end
];
}
}
Schedule Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Schedules extends Model
{
//
}
I tried to run "composer install" as I saw on other people. It seems that problem is comming from JsonResource line 55(constructor) but I don't know how to fix it. I would appreciate you're help
I found that you are passing your api resource class to response()->json(...). I also found that in your controller store method you pass Schedule which is an api resource and not a request object.
if ($schedule->save()) {
//check below since its a resource, that should be enough
return new Schedule($schedule);
} else {
return response()->json('Error can\'t save schedule', 500);
};
Perhaps sharing your error/exception would give us more details in what is happening.
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::post('login', 'UserController#login')->name('login');
Route::post('register', 'UserController#register')->name('register');
//change here below
Route::middleware(['auth:api'])->group(function(){
Route::post('details', 'UserController#details');
Route::apiResource('schedule', 'ScheduleController');
});
This may fix your issue. However, sending showing the exception would help.
I tried both solution and it does not work.
The error that I am facing is:
Illuminate\Contracts\Container\BindingResolutionException: Unresolvable dependency resolving [Parameter #0 [ <required> $resource ]] in class Illuminate\Http\Resources\Json*JsonResource* in file Illuminate\Container*Container.php on line 1032*
As stated in the doc, laravel will not fire an event on mass update/insert/delete.
https://laravel.com/docs/5.8/eloquent#events
It uses the Builder for this and will not fire an event.
Is there a way that I can still fire an event after a mass update for example? I would only need the query Builder to extract the needed info myself ( log purposes).
It is actually possible , but you have to extend the Eloquent builder ,overwrite the update/insert methods and send the event there.
Just been playing around with it... Needs work, but the basic idea is the following :
class Test extends Model
{
protected $guarded = [];
public $dispatchesEvents = [
'saved' => SavedTest::class
];
/**
* INCLUDE this as a trait in your model.
* Overwrite the eloquentBuilder.
*
* #param \Illuminate\Database\Query\Builder $query
* #return \Illuminate\Database\Eloquent\Builder|static
*/
public function newEloquentBuilder($query)
{
return new TestBuilder($query);
}
}
Extend the eloquent builder...
class TestBuilder extends Builder
{
/**
* Update a record in the database and fire event.
*
* #param array $values
* #return int
*/
public function update(array $values)
{
// normal eloquent behavior.
$result =$this->toBase()->update($this->addUpdatedAtColumn($values));
/*
* Fire event.
*/
if($result){
if( $event = Arr::get($this->model->dispatchesEvents,'saved')){
// at the attributes.
$this->model->fill($this->addUpdatedAtColumn($values));
$queryBuilder =$this->toBase();
event(new $event($this->model,$queryBuilder));
}
}
}
public function insert(array $values)
{
// same idea..
}
}
The event class :
class SavedTest
{
use SerializesModels;
public $model;
public $query;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct($model,$query =null)
{
$this->model = $model;
$this->query = $query;
}
}
The listener.
class SavedTestEvent
{
/**
* Create the event listener.
*
*
*/
public function __construct()
{
}
/**
* Handle the event.
*
* #param object $event
* #return void
*/
public function handle($event)
{
// The model , with the attributes.
dump($event->model);
// the query builder , you could extract the wheres or whatever to build your own log for it.
dump($event->query);
}
}
#Paolo on batch request it would not be file the event you must have to perform operation on single record.. like
Analytic::where('id', '>', 100)->get()->each(function($analytic) {
$analytic->delete();
});
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
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?
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']);