Laravel resource empty request parameters - laravel

When calling API route the data from query doesn't get passed to resource and the request doesn't contain any data from the query.
Route
Route::get('rooms', 'RoomController#index');
Controller
public function index() {
$rooms = Room::get();
return RoomCollection::collection($rooms);
}
Resource
public function toArray($request){
return [
'id' => $this->uid_room,
'code' => $this->room_code,
'name' => $this->name
];
}

Maybe you need Room::all() instead of Room::get()?

In controller
use App\Room;
use App\Http\Resources\Room as RoomResource;
public function index() {
$rooms = Room::all();
return RoomResource::collection($rooms);
}
In App\Http\Resources\Room.php
public function toArray($request){
return [
'id' => $this->uid_room,
'code' => $this->room_code,
'name' => $this->name
];
}

Related

Howto reusing Form Request inside loop

I am making a "/bulk" endpoint for my API/REST made in Laravel 8.
My problem is that I don't know how to reuse the same FormRequest that I have for the create or update
json post to: /cars/bulk
{
"cars": [{"model": "A", "year": 2021, "plate": "AA11BB"},{"model": "B", "year": 2021, "plate": "AA12BB"},{"model": "C", "plate": "AA13BB"}]
}
// CarController.php
public function store(CarRequest $request)
{
$car = $this->carService->store($request, Car::class);
}
public function update(CarRequest $request, Car $car)
{
$this->carService->update($request, $car);
}
public function bulk(Request $request)
{
$this->carService->bulk($request);
}
// CarService.php
public function store($request, $modelClass)
{
# My code....
}
public function update($request, $model)
{
# My code....
}
public function bulk($request)
{
foreach ($request->cars AS $carData )
{
$car = Car::where('plate','=',$carData->plate)->first()
# here is the problem,
# howto validate each $car by reusing CarRequest
if ($car){
$this->update($carData, $car);
} else {
$this->store($carData, Car::class);
}
}
}
This is de form request for each item, i have use to for bulk or one request
class CarRequest extends BaseRequest
{
public function authorize()
{
$this->setModel(Car::class);
return $this->isAuthorized();
}
public function rules()
{
$this->setModel(Car::class);
$rules = parent::rules();
$rules = [
'model' => 'required',
'year' => 'required|numeric',
'plate' => 'required'
];
return $rules;
}
public function messages()
{
# multiples messages
}
}
I need reuse my request
Edit: add form request
So I wouldn't suggest using it within a loop how you have in your example, what would be better would be to create a second, bulk request that valiates an array like this.
public function rules()
{
$this->setModel(Car::class);
$rules = parent::rules();
$rules = [
'cars' => ['required', 'array'],
'cars.*.model' => 'required',
'cars.*.year' => 'required|numeric',
'cars.*.plate' => 'required'
];
return $rules;
}
You can do it with same CarRequest form request class as follows.
public function rules()
{
return[
'cars.*.model' => 'required',
'cars.*.year' => 'required',
'cars.*.plate' => 'required',
];
}
Laravel will expect that you are sending nested array. If you dont want to mix it up with CarRequest you can do it with creating another FormRequest class.

How to use same Laravel Resource for different API response

i want to make two different functions on resource so that i can get a two different response .i.e i want the resource to return data without image and with image.
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'area_code' => $this->area_code
];
}
public function toArrayWithImages($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'area_code' => $this->area_code,
'image' => $this->image
];
}
this is what i tried but dont know how to point to the second function 'toArrayWithImages' . can someone explain me this ?
This is my controller ..
public function getAllBusinessAreas()
{
try {
$areas = Area::orderBy('id', 'desc')->get();
return BusinessAreaResource::collection($areas);
} catch (Exception $e) {
return sendErrorResponse('Error fetching Business Areas', true, 500);
}
}
what it does is by default it hits the toArray function i want to be specific which function to hit from controller. is it possible to do it ?
So basically what i am doing is adding an additional parameter to your request, you can use a flash session variable as well if it is not possible to attach extra params to your request, to filter weather it goes to the function which returns image or data without image.
public function toArray($request)
{
if($request->with_image)
{
this::toArrayWithImages($request->except('with_image'));
}
else
{
this::toArrayWithoutImages($request->except('with_image'));
}
}
public function toArrayWithoutImages($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'area_code' => $this->area_code
];
}
public function toArrayWithImages($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'area_code' => $this->area_code,
'image' => $this->image
];
}

Laravel static Model is not returning error

I have this Model UserSetting.php:
class UserSetting extends Model
{
protected $fillable = ['user_id', 'name', 'setting_value'];
public static function set($user_id, $name, $value)
{
if (!User::find($user_id)) {
return error('NoForeign_User');
}
self::updateOrCreate(
['user_id' => $user_id, 'name' => $name],
['setting_value' => $value]
);
}
}
And I want to use it this way inside UserSettingController.php:
public function user(Request $request)
{
Validator::make($request->all(), [
'user_id' => 'required|int',
'name' => 'required|string',
'setting_value' => 'required|string',
], $this->messages)->validate();
// HERE IS THE CALL
UserSetting::set($request->user_id, $request->name, $request->setting_value);
return saved();
}
I need to call UserSetting statically but NOT with a return:
return UserSetting::set(...)
But when the static function gets to the if(!User::find($user_id)) it carries on and shows the saved() helper instead of the return error('NoForeign_User')
While if I do it with a return return UserSetting::set(...) it correctly shows the error.
Is this correct? Do I have any other option other then returning the static class?
EDIT:
My error() function is this:
function error($message, $code = 422)
{
$response = ['message' => $message];
if ($errors) {
$response += [
'errors' => $errors,
];
}
return response()->json([
'message' => $message,
], $code);
}
If you don't check the result that is being returned when calling the static method, then for sure the program will continue to execute the next line which is the saved() method in your case.
In order to stop execution a better approach is to throw an exception which will propagate to the Exception handler and stop the function execution.
So instead of this:
if (!User::find($user_id)) {
return error('NoForeign_User');
}
try this:
if (!User::find($user_id)) {
throw new \Exception('NoForeign_User');
}
or yet another and the best approach in my opinion that I just remembered is to simply use the findOrFail function:
User::findOrFail($user_id);
This will also throw an exception if the user has not been found.

Error storing Topic Model into the database using Sentinel

I have a small forum, im trying to create topic and replies for the store method.
routes.php
Route::get('board/{id}/create', 'TopicsController#create');
Route::post('board/{id}/create', 'TopicsController#store');
TopicsController.php
public function store()
{
$this->request->user()->topics()->create([
'board_id' => $this->request->id,
'title' => $this->request->title,
'body' => $this->request->body
]);
return redirect(url('/board/' . $this->request->id));
}
I am receiving this error.
Call to a member function topics() on null
Also note, i am using Sentinel https://github.com/rydurham/Sentinel from this repo.
<?php namespace App\Models;
class User extends \Sentinel\Models\User
{
protected $fillable = ['email', 'first_name', 'last_name'];
protected $hidden = ['password'];
public function topics()
{
return $this->hasMany(Topic::class);
}
public function replies()
{
return $this->hasMany(Reply::class);
}
public function getGravatarAttribute()
{
$hash = md5(strtolower(trim($this->attributes['email'])));
return "https://www.gravatar.com/avatar/$hash";
}
}
Updated Model
public function store($id)
{
$user = Sentry::getUser($id);
$user->topics()->create([
'board_id' => $this->request->id,
'title' => $this->request->title,
'body' => $this->request->body
]);
return redirect(url('/board/' . $this->request->id));
}
It seems that your user object is null. Properly retrieve the user using the id
public function store($id)
{
$user = \App\Models\User::find(\Sentinel::getUser()->id);
$user->topics()->create([
'board_id' => $this->request->id,
'title' => $this->request->title,
'body' => $this->request->body
]);
return redirect(url('/board/' . $this->request->id));
}

Validation request with Laravel 5

I am trying to make validation with Laravel 5 on right way:
Here is my working code in model:
public function apiAddNewComment() {
if (Input::get("task") == 'addComment') {
$user = Auth::id();
$inputs = array(
'comment' => Input::get('comment'),
'projectID' => Input::get('projectID'),
'order' => Input::get("order"),
'level' => Input::get("level"),
);
$rules = array(
'comment' => 'required|between:15,600',
'projectID' => "required|exists:project_group,project_id,user_id,$user|numeric",
'order' => "required|numeric",
'level' => "required|numeric"
);
$validator = Validator::make($inputs, $rules);
if ($validator->fails()) {
return json_encode(array('err' => true, 'errors' => $validator->messages()->all()));
} else {
return $this->createNewComment();
}
}
}
here is my controller:
public function update($id, Comment $update)
{
return $update->apiUpdateComment();
}
How can I make validation with request?
And can someone explain me how this method works inside request:
public function authorize()
{
return false;
}
?
The Request has to basic functions: rules() and authorize()
rules returns an array that is used for the validation.
The authorize method can for example check if the user is allowed to do this request.
public function authorize() {
return Auth::check();
}
So you don't have to check it each time when you use the request in a controller.
If you need no check just return true.
UPDATE:
Generate a request File with artisan
php artisan make:request CommandRequest
then edit the generate file like this:
class CommandRequest extends FormRequest
{
public function rules()
{
return [
'comment' => 'required|between:15,600',
'projectID' => "required|exists:project_group,project_id,user_id,$user|numeric",
'order' => "required|numeric",
'level' => "required|numeric"
];
}
public function authorize()
{
return true;
}
}
Also update the controller method:
public function update($id, Comment $update, CommandRequest $request)
{
// create your comment here like:
return Comment::create($request->all());
}
You are using a Laravel 4 code I guess, you need to translate it to L5 where Input::get('var') turns into $request->input('var') for instance:
public function apiAddNewComment(Illuminate\Http\Request $request) { //Remember to add the Request as a parameter of the method
if ($request->input("task") == 'addComment') {
...
Then the validation part looks fine

Resources