Laravel 5.2 get user's notes and note's users - mysql

I have two tables:
the first
Is users table which contain user information including user id.
The Second
Is notes table which container user notes including note id.
I have relation many to many between them and I have my intermediate table between them that contain the user_id which matches note_Id.
Everything works perfectly but I want to get user notes and other users that have the same note.
For example
NOTE 1 users with id 1, 2, 3 can see it.
I want to use a query that get all the notes that the logged in user created and also other users that can view this note.
what I have tried
$usernotes = User::where('id', '=', Auth::user() -> id) -> first();
#foreach($usernotes -> notes as $usernote)
{{ $usernote -> title }}
#endforeach
This return all the user notes but doesn't return the all note's users.

This query will get users (except an authenticated one as you ask) that have the same notes a currently authenticated user has:
Note::whereHas('users', function($q) {
$q->where('id', auth()->user()->id);
})->with(['users' => function($q) {
$q->where('id', '<>', auth()->user()->id);
}])->get();

$loggedInUser = Auth::user();
#foreach($user->notes as $userNote)
Note Title: {{ $userNote -> title }}
#foreach($userNote->users as $user)
User Name: {{ $user->name }}
#endforeach
#endforeach
To exclude loggedInUser:
$loggedInUser = Auth::user();
#foreach($user->notes as $userNote)
Note Title: {{ $userNote -> title }}
#foreach($userNote->users()->where('id', '!=', $loggedInUser->id)>get() as $user)
User Name: {{ $user->name }}
#endforeach
#endforeach

Related

How can we show the product of different type separately?

I have two type of products. Book and cd. Book has number of pages and cd has playlength. I kept a condition for edit, update and delete and it's working fine. In index function of Product Controller, I showed all products and its showing but when I need to display it in product.blade.php what condition should be kept to show this product differently. For eg: if product is book it's page number should be shown and if it's cd then it's play length should be shown. The column in database is papl for both.
ProductController.php
public function index()
{
$products=product::all();
return view('mainAdmin/products', ['products'=>$products]);
}
public function show(Product $product)
{
if($product->type == 'Book')
return view('mainAdmin/bookProduct', ['product'=>$product]);
if($product->type=='cd')
return view('mainAdmin/cdProduct', ['product'=>$product]);
//return view('singleProduct', ['product'=>$id]);
}
products.blade.php
#foreach($products as $product)
Title:{{ $product->title}}<br>
Type:{{ $product->type}}<br>
Firstname:{{ $product->firstname}}<br>
Surname:{{ $product->surname}}<br>
Price:£{{ $product->price}}<br>
PageNumber:{{ $product->papl }}<br>
Show
Edit<br/>
<p>--------------------------------------------------------------------------</p>
#endforeach
Database:
enter image description here
you can use blade #if #else
#foreach($products as $product)
Title:{{ $product->title}}<br>
Type:{{ $product->type}}<br>
Firstname:{{ $product->firstname}}<br>
Surname:{{ $product->surname}}<br>
#if ($product->type == 'cd')
Price:£{{ $product->price}}<br>
#endif
#if ($product->type == 'Book')
PageNumber:{{ $product->papl }}<br>
#endif
Show
Edit<br/>
<p>--------------------------------------------------------------------------</p>
#endforeach
ref link https://laravel.com/docs/8.x/blade#if-statements

Bootstrap button with a badge counter not working

I have a Bootstrap button with a badge counter (a numerical indicator of how many items are associated with the link).
Events <span class="badge badge-light">{{ $events = Event::where(['status' => 0])->count() }}</span>
The link works OK, but the badge counter isn't working. It should check how many events are in the database and show that number on the badge counter. So, something is wrong with this line:
{{ $events = Event::where(['status' => 0])->count() }}
I tried adding to my Events controller
public function events()
{
return view('groups.index', [
'count' => Event::where(['status' => 0])->count(),
]);
}
and calling {{ $count }}
but I get this error
Call to a member function count() on null (View: C:\laragon\www\version2\resources\views\groups\index.blade.php)
Note: The button needs to count the number of event, but the button itself shows on the groups.index page (mentioned for clarity)!
Extract logic in controller.
use \App\Event; // use your model
public function someMethod()
{
// other code
return view('some.view', [
'count' => Event::where(['status' => 0])->count(),
]);
}
view:
Events <span class="badge badge-light">{{ $count }}</span>

How to join 2 tables and group them by parent table id in laravel?

I have 2 tables:
t1: hotels
t2: people
There are 5 hotels and in every hotel a different number of people.
I'd like to get hotel name and people's names assigned to that hotel.
With the query I have it duplicated the hotel name as many times as there are people in it.
$hotels=DB::table('hotels')
->select('hotels.*','people.name')
->leftjoin('people','people.hotel_id','=','hotel.id')
->get();
return view('hotels', ['hotels' => $hotels]);
And in my view I have
#foreach($hotels as $h)
$h->hotel_name
#endforeach
hotel_name now shows up 4 times which is the same number of people assigned to the hotel_id.
I've tried using group_concat but with that I could only get the names of the people.
Is there a group by or some other method which could help me to get to my goal?
In your HotelModel
public function peoples()
{
return $this->hasMany('App\People','hotel_id');
}
In your Controller
(use ->with('peoples') to solve the n+1 problem.
$hotels = Hotel::with('peoples')->get();
return view('hotels', ['hotels' => $hotels]);
In your View
#foreach($hotels as $h)
$h->hotel_name
#foreach($h->peoples as $people)
$people->name
#endforeach
#endforeach
Actually you can achieve this using group_concat and group_by like so :
select hotels.* ,group_concat(people.name) as people_names
from hotels
left join people on hotels.id = people.hotel_id
group by hotel_name;
using the query builder :
$hotels = DB::table('hotels')
->select('hotels.*', DB::raw('group_concat(people.name) as people_names'))
->leftjoin('people','people.hotel_id','=','hotels.id')
->groupBy('hotel_name')
->get();
Add to your Hotel class
public function peoples()
{
return $this->hasMany(People::class);
}
In your view:
#foreach ($hotel->people as $people)
{{ $people->name }}
#endforeach
Try to use Collection's groupBy function:
$hotels=DB::table('hotels')
->select('hotels.*','people.name')
->leftjoin('people','people.hotel_id','=','hotel.id')
->get();
$grouped = $hotels->groupBy('hotel_name');
return view('hotels', ['hotels' => $grouped]);
And then, print it like this:
#foreach($hotels as $key => $h)
Hotel name: {{ $key }}
#foreach ($h as $p)
Person name: {{ $p }}
#endforeach
#endforeach
Make a Hotel model and define the relationship:
public function people()
{
return $this->hasMany(People::class);
}
I'm your controller:
$hotels = Hotel::all():
return view('hotels')->with('hotels', $hotels);
In your view:
#foreach($hotels as $hotel)
{{ $hotel->name }}
#foreach($hotel->people as $person)
{{ $person->name }}
#endforeach
#endforeach

Retrieving data from junction table via foreign key - Laravel

I'm trying to get data from a junction table and display it, so I have a users table and my junction table prescription_user. Prescription_user table has a user_id and prescription_id.
So what I'm trying to do is on this userdetails page, show all of this users prescriptions and access the prescription name and description etc, however when I try any of this I get "Trying to get property of non-object"
The models are set up to eager load correctly I think, the user model has a hasMany relation with the prescription_user model, and the prescription_user model has a belongsTo the user model.
Controller
function viewUserDetails($userId)
{
$logged_user_id = Auth::user()->id;
$user = User::find($logged_user_id);
$prescriptions = Auth::user()->prescription_user;
$fullname = $user->firstname ." ". $user->surname;
$email = $user->email;
$address = $user->address;
$postcode = $user->postcode;
$dob = $user->dateofbirth;
$uniquepatientnumber = $user->uniquepatientnumber;
$data = [];
$data['fullname'] = $fullname;
$data['email'] = $email;
$data['address'] = $address;
$data['postcode'] = $postcode;
$data['dateofbirth'] = $dob;
$data['uniquenumber'] = $uniquepatientnumber;
$data['prescriptions'] = $prescriptions;
return view('user/userdetails')->withData($data);`
userdetails blade
#extends('layouts.master')
#section('title', 'My Details')
#section('content')
<h1>My Details </h1>
<ul>
<li>Name: {{ $data['fullname'] }}</li>
<li>Email: {{ $data['email'] }}</li>
<li>Address: {{ $data['address'] }}</li>
<li>Postcode: {{ $data['postcode'] }}</li>
<li>Date of Birth: {{ $data['dateofbirth'] }}</li>
<li>Your Unique number is: {{ $data['uniquenumber'] }}</li>
<li>Your are currently prescribed {{$data['prescriptions']}}</li>
<p>Note: If you believe any of these are incorrect please contact a receptionist</p>
</ul>
#endsection``
There are some design flaws in what you have explained. You have a User model and a Prescription model. That means prescription_user is your pivot table (not junction table). If so far I'm correct, it means User and Prescription have a Many to many relationship. To prove my point, you said
Prescription_user table has a user_id and prescription_id.
That means prescription_user is the pivot table.
In your user model, define a many to many relationship with prescription. And vice versa.
User model
public function prescriptions() {
return $this->belongsToMany(Prescription::class, 'prescription_user', 'user_id', 'prescription_id');
}
Then you can change your controller function like this
public function viewUserDetails()
{
$user = Auth::user();
$prescriptions = $user->prescriptions;
return view('user/userdetails', compact('user', 'prescriptions'));
}
And your view
#extends('layouts.master')
#section('title', 'My Details')
#section('content')
<h1>My Details </h1>
<ul>
<li>Name: {{ $user->firstname }} {{ $user->surname }}</li>
<li>Email: {{ $user->email }}</li>
<li>Address: {{ $user->address }}</li>
<li>Postcode: {{ $user->postcode }}</li>
<li>Date of Birth: {{ $user->dateofbirth }}</li>
<li>Your Unique number is: {{ $user->uniquepatientnumber }}</li>
</ul>
Your are currently prescribed
<ul>
#foreach($prescriptions as $prescription)
<li>{{ $prescription->name }}
#endforeach
</ul>
<p>Note: If you believe any of these are incorrect please contact a receptionist</p>
#endsection
Your code would be neater and working great
Update
Getting data from the pivot table is relatively simple. Define those columns in the relationship
public function prescriptions() {
return $this->belongsToMany(Prescription::class, 'prescription_user', 'user_id', 'prescription_id')->withPivot('column1', 'column2');
}
In your view, you display it like this
{{ $prescription->pivot->column1 }} {{ $prescription->pivot->column2 }}
First I'm not sure that withData() is a thing. Just ->with($data).
Second, there is some confusion at the beginning of your function. You pass in a $userId, that you never use. Then you get the id from Auth::user(), then get a user with that id, which you already had. So just $user = Auth::user();
Third, you only get that error trying to use the -> operator on a non-object, and you only use it on $user-> and Auth::user()->
Since you got the user from Auth::user in the first place, I'm guessing it failed right out of the box at Auth::user()->id, and there is no Auth::user, but you would have to post a little more data, either from the error in the browser or from storage/logs/laravel.log.
BUT, if I use this code
Route::get('/', function () {
$user = \Auth::user();
die($user->name);
return view('welcome');
}
where there clearly is no Auth::user() (I haven't even got to a login yet) I get this output:
ErrorException in web.php line 16:
Trying to get property of non-object
1. in web.php line 16
2. at HandleExceptions-> ... array('user'=>null)
So it's probaby that.

Issue when trying to populate a drop-down with database values

I am using the following HTML to show a selected drop down with values from the database and rest of the others in the list. It shows the selected name correctly but the selected is also displayed in the list.
How to remove the second time show selected name in the drop down list? Is this a good way to use drop down menu? Here Jobcategory and Jobdetails are associated.
Im using Laravel 4.2 and this is the HTML:
// view drop down form to save data
<div class="large-6 columns">
<label>Job Category
<select name="category[]">
<option value="">Select Category</option>
#foreach(JobCategory::all() as $jcat)
<option value="{{ $jcat->id }}">{{ $jcat->name }}</option>
#endforeach
</select>
</label>
</div>
// Edit drop down form to update the selected value
<div class="large-6 columns">
<label>Job Category
<select name="category[]">
<option value="{{$jobedit->jobcategory->id}}">{{$jobedit->jobcategory->name </option>
#foreach(JobCategory::all() as $jcat)
<option value="{{ $jcat->id }}">{{ $jcat->name }}</option>
#endforeach
</select>
</label>
</div>
// database table for jobcategories
id | name
1 | Accounting/Finance
2 | Advertisement/Event Mgt.
3 | .....
// after save into jobdetails table
id | jobcategory_id | .......
1 | 5 | ...
I can retrieve the value of jobcategory in the edit form but it shows twice one in the selected value and other in the listed value of all jobcategory. This is the problem and i want only show the selected value and then rest of the others from jobcategory table without duplicate value of selected in the drop down. plz help.
// controller to to edit
public function getJobEdit($id)
{
$jobedit = JobDetail::find($id);
return View::make('employers.edit_single_jobs')->with('jobedit', $jobedit);
}
// JobDetail --model
public function jobcategory()
{
return $this->belongsTo('JobCategory');
}
// JobCategory --model
public function jobdetails()
{
return $this->hasMany('JobDetail', 'jobcategories');
}
Have a look at the Forms & HTML helper of laravel.
Generating A Drop-Down List With Selected Default
echo Form::select('size', array('L' => 'Large', 'S' => 'Small'), 'S');
where the first argument is the name of the select box. The second argument is an array of all entries in the box and the last argument determines which of the array elements is the selected one.
in your case it could look something like this:
{{ Form::select(
'categoryName',
array(
'Accounting/Finance' => 'Accounting/Finance',
'Advertisement/Event Mgt.' => 'Advertisement/Event Mgt.',
// to be continued ...
),
'$cat->category_name'
); }}
//Edit
<div class="large-6 columns">
<label>Job Category
{{ Form::select('category[]', ['' => 'Select a category'] + $all_categories, $jobedit->jobcategory->id) }}
</select>
</label>
</div>
where $all_categories should be an array of all categories as in the first example. You can get this from JobCategory::all().
This is how I set up drop-downs in my projects. I prepare the data in my controller (you'd obviously need a route and controller set up for this, I'm assuming you've done that):
Controller
public function index()
{
$categories = \Category::lists('name', 'id')->orderBy('name'); // assuming you have a Category model
view('categories', compact('categories'));
}
Then you can use the Forms and HTML helper as Peh mentioned, this isn't available as a default in Laravel 5 so you'd need to add it into your project using composer. To do so either run composer install illuminate/html or add "illuminate/html": "~5.0" to your composer.json file and then run composer install. You'd then need to add 'Illuminate\Html\HtmlServiceProvider' to config/app.php in the providers array then add 'Form' => 'Illuminate\Html\FormFacade' and 'HTML' => 'Illuminate\Html\HtmlFacade' to the aliases array in the same file. Once that's sorted you can use the Form and HTML helper in your view, as so:
View
{{ Form::select('categoryName', ['' => 'Select a category'] + $categories) }}
Your view would need to be saved as filename.blade.php if using the handlebars, otherwise echo it within <?php ?> tags.
Hope that helps you on your way.