Laravel 8 and Swagger: how to document responses with different relationships - laravel

I'm using darkaonline/l5-swagger package (Laravel: 8.83.27, PHP: 7.4.33). I'm trying to document my Passport based API. Here's my index action in the user controller:
$query = User::query()
->with(['roles', 'permissions'])
->orders('id', 'desc');
As you can see here I'm returning entire User model and related roles and permissions. In the store() action, my response looks like this:
$user = new User();
$user->fill($request->only($user->getFillable()));
if ($user->save()) {
$roles = $request->roles;
if (is_array($roles)) {
$user->assignRole($roles);
}
$permissions = $request->permissions;
if (is_array($permissions)) {
$user->givePermissionTo($permissions);
}
}
return new BaseResource($user);
Here I'm returning User model only (without roles and permissions). How can I use #OA\Response annotation and document these different responses? I'm brand new to Swagger.

Related

How to find user by user name in laravel?

I am trying to find user by user name while building a laravel API. This is what I'm trying
api.php
Route::get('user-profile/user/{user}', 'UserProfileController#getUserProfile');
Controller
public function getUserProfile(User $user)
{
$userId = User::where('userName', $user->userName)->first()->id; // I am expecting user id here like "1"
}
This causing 404 not found error.
By default route model binding will search for id.
You should customise the column name in your route if you want Laravel to select the user using the column userName.
In you api.php:
Route::get('user-profile/user/{user:userName}', 'UserProfileController#getUserProfile');
Assuming that your userName is unique in the table, then in your controller you should use:
public function getUserProfile(User $user)
{
$userId = user->id;
...
}
This will automatically handle 404 errors for you as opposed to this answer.
by default route model binding search for id and in your case you want search by username so all you need is to remove dependency injection from your controller parameters like this
public function getUserPortfolio($user) // fix it as $user only
{
$userId = User::where('userName', $user)->first()->id; // I am expecting user id here like "1"
}

Laravel Intermediate relations data error

Here is my RecentViewController file code:
$contents = RecentView::where('user_id', $loggedUser)
->with('posts')
->with('profile')
->paginate(12)->toArray();
and my RecentView model code is as follows:
public function posts()
{
return $this->hasOne('App\FeedPost', 'id', 'post_id');
}
public function profile()
{
return $this->belongsTo('App\Profile', 'user_id', 'id');
}
the data i receive after running this code shows logged in users details instead of posts users detaisl. how can i change retreiving posts users data instead of logged users data?
I guess you are trying to get the user of the post
In order to get posts users detail you need to move profile relation into Post model. I hope there's a user_id in posts table. then get profile relationship of post model with dot notation as follows
$contents = RecentView::where('user_id', $loggedUser)
->with('posts.profile')
->paginate(12)->toArray();

Get all posts from users that are not blocked in Laravel?

I have a Laravel 5.8 application where one user can block another user.
User model:
public function blockedUsers()
{
return $this->belongsToMany(User::class, 'blocked_user', 'user_id', 'blocked_id');
}
Now every user can post articles. How to get all articles that are posted by non blocked users in users feed.
If I do:
$posts = Post::all();
Obviously I will get all posts, so how to make a where conditin and say all posts that are created by a user which is not blocked by Auth::user()?
$user = Auth::user();
$posts = Post::where(function($q) use ($user){
// Can't figure out this part
})->get();
You can first get your blocked user ids and use it later in the query to check if the creator of the post is one of the blocked ids using whereNotIn()
$user = Auth::user();
// Get list of blocked user ids
$blockedIds = $user->blockedUsers->pluck('id')->toArray();
// NOTE: I am assuming the field that hold the post creator id is user_id
// Get all post where the creator id is not in the blocked ids array
$posts = Post::whereNotIn('user_id',$blockedIds)->get();
Alternatively you can also write it like this
$user = Auth::user();
$posts = Post::where(function($q) use ($user){
$q->whereNotIn('user_id', $user->blockedUsers->pluck('id'))
})->get();
$user_id = Auth::id();
// get all blocked users by auth user
// note: you need to create BlockedUser model for blocked_user table
$blocked_users=BlockedUser::where('user_id',$user_id)->pluck('blocked_id');
// get all posts without posts that created by blocked users
Post::whereNotIn('user_id',$blocked_users)->get();

get user from belongsToMany relationships

I have a service model in October CMS.
In this model, I need to get postman's users (postman is user group) but I am receiving this error:
Trying to get property of non-object
This is my code
public function getPostmanIdOptions()
{
$groups = UserGroup::where('id','4')->lists('name', 'id');
$groups->users;
$list = [' ' => 'choose'] + $groups;
return $list;
}
At the moment, your lists() function will only return the name and the id of each user group. This is used to return thelselect options for the backend select (I am assuming).
What you need to do in this case is return the record based on its id which can be done using the find() eloquent method.
By doing this, the full UserGroup model will be returned, with it's relationships etc.
You're new code should look something like this:
...
$group = UserGroup::find(4);
$users = $group->users;
...
After retrieving the users, you can then using the lists() method if required to:
$list = $group->users->lists('name', 'id');

How can fill the user id field with auth user on creation of resource?

I'm sure there must be a very simple way to do this - I would like to fill the user_id field on my resource with the authenticated user's id whenever a new instance of the resource is created.
In the store() method of my Resource model I have:
public function store(Request $request)
{
$input = $request->all();
$resource = Resource::create($input);
$resource->user_id = Auth::user()->id;
return $resource;
return 'Resource added.';
}
This works through a post API route, however whenever I add a new resource instance through Nova dashboard, it does not add the Auth user id. I'm guessing this because Nova doesn't use that Resource controller that I have set out?
I would appreciate suggestions!
Working on the assumption that you have relationship method User::resources() the following should work:
return $request->user()->resources()->create($request->all());
The way you have it doesn't work because you didn't save the resource after associating user with it.
I haven't used Nova yet, but since its also laravel and most likely Eloquent ORM I can tell the following.
In these two lines you've set the user_id but you haven't persisted the change:
$resource->user_id = Auth::user()->id;
return $resource;
You should add this line to save the changes you've done:
$resource->save();
As an alternative you could add the value already into your $input array:
$input = $request->all();
$input["user_id"] = Auth::user()->id;
$resource = Resource::create($input);
I just created an ResourceObserver. Saved the Auth()->user->id with the created method.
Registered the ResourceObserver to AppServiceProvider and NovaServiceProvider.
https://laravel.com/docs/5.7/eloquent#observers
https://nova.laravel.com/docs/1.0/resources/#resource-events
In the model class, add function like this:
public function save(array $options = array())
{
$this->user_id = auth()->id();
parent::save($options);
}
Just be carefull if you tend to use save in any other scenario so you don't overwrite existing user_id.

Resources