Laravel - Comparing a database value with a variable - php

I have a basic appointment system set up, however everybody logged in can see all appointments, so what I'm trying to do is make it so users can only see their appointments. To do this I'm trying to get the logged in users Id then display all the appointments that have this user_id value (Appointments is a junction table)
I know my code is probably awful but any help is appreciated, thanks
function index()
{
$logged_user_id = Auth::user()->id;
$user = User::find($logged_user_id);
$appointments = Appointment::where('user_id', '=' $user)->get();
return view ('appointment/userappointments',['appointments' => $appointments]);
// $appointments = Appointment::all();
}

Set up your model relations and you can just do this
function index()
{
$appointments = Auth::user()->appointments;
return view ('appointment/userappointments',['appointments' => $appointments]);
}

You already have the user id, dont have to fetch User info.
function index()
{
$logged_user_id = Auth::user()->id;
$appointments = Appointment::where('user_id', '=' $logged_user_id)->get();
return view ('appointment/userappointments',['appointments' => $appointments]);
//$appointments = Appointment::all();
}

Related

How Can I get Latest 5 Commentors user information By Laravel Relational Eloquent eager loading

I'm in a situation where I need to display the last 5 unique commenters information at the top of the comment list as follows screenshot.
comment image
To do this. I did as follows:
Post Model
public function comments()
{
return $this->hasMany(Comment::class);
}
public function commenter_avatars(){
return $this->comments()->distinct('user_id')
->select('id','post_id','user_id','parent_id')
->whereNull('parent_id')
->with('user')->limit(5);
}
My Controller method as follows
public function index() {
$feeds = auth()->user()
->posts()
->with(['user:id,first_name,last_name,username,avatar', 'media', 'commenter_avatars'])
->orderBy('id', 'desc')
->paginate(10);
return PostResource::collection($feeds);
}
I tried to use groupBy and Distinct.. But did't work as expected.
Did I miss something? or Have there any more best way to solve this?
Thank you in advance!
Noted: I am using latest Laravel (8.48ˆ)
I don't know about your joining of post, user and comments table. But i guess, you can do something similar to following.
At first get latest 5 unique user id of one post:
$userIds = Comments::where("post_id", $post_id)->distinct("user_id")->orderBy("id")
->limit(5)->pluck('user_id');
Then, fetch those user information
$users = Users::whereIn("id", $userIds )->get();
Then, you can return those users
UPDATE
You may use map() to fetch and reorder output. Following is an idea for you:
In Controller:
public function index(Request $request) {
$skipNumber = $request->input("skip"); // this is need for offsetting purpose
$userIds = [];
$feeds = Posts::with("comments")->where("comments.user_id", Auth::id())
->skip($skipNumber)->take(10)->orderBy('comments.id', 'desc')
->map(function ($item) use($userIds){
$users = [];
$count = 0;
foreach($item["comments"] as $comment) {
if(!in_array($comment["user_id"], $userIds) && $count < 5){
$count++;
$userIds.push($comment["user_id"])
$user = User::where("id", $comment["user_id"])->first();
$users.push($user);
}
if($count == 5) break;
}
$data = [
"post" => $item,
"latest_users" => $users
];
return $data;
})->get();
return PostResource::collection($feeds);
}
My code syntax may be slightly wrong. Hopefully you will get the idea.
I have solved this issue by using eloquent-eager-limit
https://github.com/staudenmeir/eloquent-eager-limit

Laravel Blade Multiple Values in DB Table

Little question: Currently I've a route
Route::get('update/{id?}', 'SessionController#onClick');
That loads with this function:
public function onClick($id, Request $request)
{
$data = $request->all();
$user = User::where('userRooms', $id)->first();
return view('sessions.cards')->with('user', $user);
}
I want that my blade view displays all users that have access to this room, currently I hard coded everything. My question is now, what do I have to write down in my code so that users have access to multiple rooms and not just one(userRooms row in my db for User::Class) & how I can display all users that have this room?
I hope I understood your question correctly. Try this way:
public function onClick($id, Request $request)
{
$data = $request->all();
$users = User::where('userRooms', $id)->get();
return view('sessions.cards', [
'users' => $users,
]);
}

Get and updating JSON arrays

In a Laravel application, I store details about a user in another table called profiles and I decided it would be a good idea to store one column as a simple JSON array.
This column is called socialProfiles
Here is my index method of ProfilesController
public function index()
{
$user = auth()->user();
if($user)
{
$profile = $user->profile;
if(!$profile)
{
// Define the social profiles array
$socialProfiles = [
'Facebook' => '',
'Twitter' => ''
];
$profile = new Profile();
$profile->user_username = $user->username;
$profile->mangedByUsername = $user->managedByUsername;
$profile->socialProfiles = json_encode($socialProfiles);
$profile->save();
}
$socialProfiles = json_decode($user->profile->socialProfiles, true);
return view('editable.people.profile', compact('user', 'socialProfiles'));
}
}
I set default values of nothing for both Facebook and Twitter and encode them as a JSON string, I then return the user and the profiles to the view.
In the view I have individual forms (within modals) that update different parts of a user profile, and they all go to the same method, because of this, my update function looks like this:
public function update(Request $request)
{
// TODO: Add validation before updating or adding the profile
$this->validate(request(), [
'background' => 'min:1',
'skills' => 'min:1',
]);
$user = auth()->user();
if($user)
{
// Only proceed if there is a logged in user
$profile = $user->profile;
// If there is no profile, create one for this user as they'll need one.
if (!empty(request()->get('background')))
{
$profile->background = $request->get('background');
}
if (!empty(request()->get('skills')))
{
$profile->skills = $request->get('skills');
}
if (!empty(request()->get('filepath')))
{
$profile->displayPicture = $request->get('filepath');
}
$profile->user_username = $user->username;
$profile->save();
return redirect()->back()->withSuccess('Your profile has been successfully updated');;
}
}
If I'm going to be updating the social profile JSON array would i need to recreate the array, encode it and then save it?
The reason for the separate modals is because the design looks like this:
Should I have many separate update methods?
What is your DBMS system, are you using Postgres JSON column?
If you are saving it like this $profile->socialProfiles = json_encode($socialProfiles);
You are saving it as JSON, which is fine. But if you need to update it, you have two choices, modify the original JSON column with some additions, or a create a new column socialProfileUpdates create a new JSON entry on this with the updated profile links. I won't recommend modifying the original JSON entry each time the user updates the record because this way your system would be really buggy.

Laravel how to insert my auth user id to my database upon submission?

im using laravel 5.4
upon submitting the form, the user_id of the submitter will be inserted in the database. and im not sure if its the right way so if you have any idea please help me thanks
can anyone help me please this my controller as of now.
public function index()
{
$user = Auth::user();
$rfq_table = $user->rfq_table;
return view('admin.sales.rfq.index',compact('rfq_table'));
}
public function create()
{
return view('admin.sales.rfq.create',compact('rfq_table'));
}
public function store(Request $request)
{
$user=Auth::user();
$rfq= $user->rfq_table()->create($request->all());
return redirect()->route('admin.sales.rfq.index');
}
I'm not sure how your DB looks, but you can create a var $user_id = Auth::user()->id; and save that in your DB
If you are using a form, insert the session user id like this in your insert controller:
Create your variable out of the user()'s id:
$user_id = Auth::user()->id;
Then use the variable here:
$insert->usr_id = $user_id;
$insert->postcode = request('postcode');
Your Other Inserts from your submitted form go here.

Laravel previous and next records

I am trying to create a page where I can see all the people in my database and create edits on them. I made a form where I fill in the data from the database of certain fields.
I would like to navigate trough them by a Next and Previous button.
For generating the next step I have to take the ID larger than the current one to load the next profile.
For generating the previous step I have to take the ID smaller than the current one to load the previous profile.
My route:
Route::get('users/{id}','UserController#show');
Controller:
public function show($id)
{
$input = User::find($id);
// If a user clicks next this one should be executed.
$input = User::where('id', '>', $id)->firstOrFail();
echo '<pre>';
dd($input);
echo '</pre>';
return View::make('hello')->with('input', $input);
}
View:
The buttons:
Next
What is the best approach to get the current ID and increment it?
Below are your updated controller and view files derived from #ridecar2 link,
Controller:
public function show($id)
{
// get the current user
$user = User::find($id);
// get previous user id
$previous = User::where('id', '<', $user->id)->max('id');
// get next user id
$next = User::where('id', '>', $user->id)->min('id');
return View::make('users.show')->with('previous', $previous)->with('next', $next);
}
View:
Previous
Next
// in your model file
public function next(){
// get next user
return User::where('id', '>', $this->id)->orderBy('id','asc')->first();
}
public function previous(){
// get previous user
return User::where('id', '<', $this->id)->orderBy('id','desc')->first();
}
// in your controller file
$user = User::find(5);
// a clean object that can be used anywhere
$user->next();
$user->previous();
In your App\Models\User.php
...
protected $appends = ['next', 'previous'];
public function getNextAttribute()
{
return $this->where('id', '>', $this->id)->orderBy('id','asc')->first();
}
public function getPreviousAttribute()
{
return $this->where('id', '<', $this->id)->orderBy('id','asc')->first();
}
In your Controller you can simply do this:
public function show(User $user)
{
return View::make('users.show')
->with('user', $user)
->with('previous', $user->previous)
->with('next', $user->next);
}
I understand the approach being taken here by user2581096 but I am not sure it is efficient (by any standards). We are calling the database 3 times for really no good reason. I suggest an alternative that will be way more efficient and scalable.
Do not pass the previous and next IDs to the view. This eliminates 2 unnecessary database calls.
Create the following routes:
users/{id}/next
users/{id}/previous
These routes should be used in the href attributes of the anchor tags
Add methods in the controller to handle each of the new routes you have created. For example:
public function getPrevious(){
// get previous user
$user = User::where('id', '<', $this->id)->orderBy('id','desc')->first();
return $this->show($user->id);
}
This function will only be called when you actually click on the button. Therefore, the database call is only made when you need to actually look up the user.
in-case you want to retrieve the prev/next records along with their data,
you can try
$id = 7; // for example
$prev = DB::table('posts')->where('id', '<', $id)->orderBy('id','desc')->limit(1);
$next = DB::table('posts')->where('id', '>', $id)->limit(1);
$res = DB::table('posts')
->where('id', '=', $id)
->unionAll($prev)
->unionAll($next)
->get();
// now $res is an array of 3 objects
// main, prev, next
dd($res);
1- the query builder is usually much faster than eloquent.
2- with union we are now only hitting the db once instead of 3.
To get next and previous post we can use max and min functions on Model id in laravel. here is an example to get this
https://usingphp.com/post/get-next-and-previous-post-link-in-laravel
The Controller:
public function post($id)
{
$post = Post::find($id);
$previous = Post::where('id', '<', $post->id)->max('id');
$next = Post::where('id', '>', $post->id)->min('id');
return view( 'post', compact( 'post', 'next', 'previous' ));
}
The View:
#if($next)
{{$next->title}}
#endif
#if($previous)
{{$previous->title}}
#endif
Here's a link I found that should help: http://maxoffsky.com/code-blog/laravel-quick-tip-get-previous-next-records/
It looks like for next you want to use: $next = User::where('id', '>', $id)->min('id'); and have the view as: Next
Also don't forget to pass $next to the view.
Simplest approach
// User.php
public static function findNext($id)
{
return static::where('id', '>', $id)->first();
}
// UserController.php
$nextUser = User::findNext($id);
// view
Next
Lazy approach :
// view
Next
// routes.php (should be optimized, this is just to show the idea)
Route::get('users/{user}/next', function($id) {
$nextUser = User::findNext($id);
return Redirect::to('user/' . $id);
});
// yourModel.php
public function previous()
{
return $this->find(--$this->id);
}
public function next()
{
return $this->find(++$this->id);
}
Works like magic, you can chain it:
$prevprev = Model::find($id)->previous()->previous();
$nextnext = Model::find($id)->next()->next();
First, get a record out of the database.
$post = Post::where('slug', $slug)->first();
With a database record, we can get the previous record where the record id is less than the id stored inside $post order by the id in descending order and use first() to get a single record back.
$previous = Post::where('id', '<', $post->id)->orderBy('id','desc')->first();
To get the next record it's almost the same query, this time get the record where the id is more than the id stored in $post.
$next = Post::where('id', '>', $post->id)->orderBy('id')->first();
Controller:
public function show($id)
{
// get the current user
$user = User::find($id);
// get previous user id
$previous = User::offset($user->id-2)->first();
// get next user id
$next = User::offset($user->id)->first();
return View::make('users.show')->with('previous', $previous)->with('next', $next);
}
i developed the code.
it work all times, even if we don't have any next or prev post
public function nextPost($table, $id)
{
$next = DB::table($table)->where('id', '>', $id)->orderBy('id','asc')->first();
if(!$next)
$next = DB::table($table)->orderBy('id','asc')->first();
return $next;
}
public function prevPost($table, $id)
{
$prev = DB::table($table)->where('id', '<', $id)->orderBy('id','desc')->first();
if(!$prev)
$prev = DB::table($table)->orderBy('id','desc')->first();
return $prev;
}

Categories