laravel5.1 retrieve nested relation using eloquent hasOne() (one to one relation) - php

My table design is:
users: | id |username | ... |
tickets: | id | supp_id | ... |
ticket_replies: | id | ticket_id | user_id |
My controllers look like:
user:
public function tickets()
{
return $this->hasMany('App\ticket');
}
ticket:
public function ticket_replie()
{
return $this->hasMany('App\ticket_replie');
}
public function supporter()
{
return $this->hasOne('App\User', 'id','supp_id');
}
My controller looks like this:
$tickets = Auth::user()->tickets()->orderBy('status', 'desc')->paginate(2);
return view('protected.ticketsList', [
'tickets' => $tickets,
]);
In my view I use:
supporter: {{ $ticket['supporter']->username }}
Any idea where I do wrong? I get all the time this error:
Trying to get property of non-object
In my point of view the relation between the tables itself is done correctly.
When I use for example {{ dd($ticket) }} in my view I get an object with all the items I need:

So first of all, trying to access the function public function supporter() on your Ticket model cannot be done using array syntax. Change:
{{ $ticket['supporter']->username }}
to:
{{ $ticket->supporter()->first()->username }}
If you don't want to use the ->first() you can do one of two things. Modify your existing query to include the ->with("supporter") syntax:
$tickets = Auth::user()
->tickets()
->with("supporter")
->orderBy('status', 'desc')
->paginate(2);
And access the supporter from the view like so:
{{ $ticket->supporter->username }}
// Notice how supporter is no longer a `method` ->supporter() but a `property` ->supporter
Or you can modify your relationship to include the closer ->first():
public function supporter(){
return $this->hasOne('App\User', 'id','supp_id')->first();
}
And then access it like so:
{{ $ticket->supporter()->username }}
// Notice you no longer need `->first()`
So, as you can see, there are multiple ways to access a Ticket's Supporter. Please note that you can't really combine these options; modifying the function to include ->first() and then trying to use ->with() will return an error, so pick one or the other.
Hope that helps!

Related

select few from one table and based on value fetch from another table

I have three tables:
Products
id
other values
Downloads
id
user_id
product_id
Users
id
name
I'd like to fetch last X Download table rows, get their product_id & user_id, product_id match Product table as user_id match User table, then make
foreach ($values as $value) {
<div class="product_title"> {{$product->name}} </div>
<div class="who_downloaded"> {{$user->name}} </div>
}
I can pass in my controller Download model, but it doesn't get me anywhere close
public function index() {
return view('nav/index', [
'trendings' => Template::orderBy('views', 'DESC')->where('is_active', 'yes')->take(8)->get(),
'latests_downloads' => Downloads::orderBy('id', 'DESC')->take(8)->get(),
]);
}
'latests_downloads' => Downloads::orderBy('id', 'DESC')->take(8)->get() function just gives me:
id
user_id
product_id
1
7
10
2
9
2
3
45
86
4
88
85
5
5
2
6
7
7
7
5
5
8
9
6
But how can I take these values and put in view?
Add the following methods to your Download model class (If they don't already exist.)
public function user()
{
return $this->belongsTo(User::class, 'user_id');
}
public function product()
{
return $this->belongsTo(Product::class, 'product_id');
}
Change your controller.
'latests_downloads' => Downloads::orderBy('id', 'DESC')->take(8)->get(),
// replace with the following
'latests_downloads' => Downloads::with(['user', 'product'])->orderBy('id', 'DESC')->take(8)->get(),
Fetch it in your view file.
#foreach($latest_downloads as $latest_download)
User Id: {{ $latest_download->user->id }}
Product Id: {{ $latest_download->product->id }}
#endforeach
Yes for this type of scenario you need to use a relationship-based Eloquent model query of Laravel and it is very powerful for this type of scenario.
First You need to add two relationships in the Download model :
public function user()
{
return $this->belongsTo(User::class, 'user_id');
}
public function product()
{
return $this->belongsTo(Product::class, 'product_id');
}
And rest of the things work well with this single query.
// user this query
$latest_downloads = Downloads::with(['user', 'product'])->latest()->take(8)->get();
instead of => getting two different queries in two different variables.
You only need to get a single collection of records in a minimum query and a minimum number of variables. You can do it with Eloquent easily.
And last you can use inside blade as like normal we use daily.
#foreach($latest_downloads as $key => $latest_download)
User ID: {{ $latest_download->user->id ?? '' }}
Product ID: {{ $latest_download->product->id ?? '' }}
#endforeach

Laravel - Get additional column value from pivot table

I have Stores and Medicines tables with many to many relationship. Storing and updating work fine with attach and sync. The table structure is like below. I want to retrieve value of extra column (expired).
store_id | medicine_id | expired
1 2 1
1 3 0
Also I need to count total medicines which expired like this
Both models have withPivot('expired') model relation.
Controller
public function show($id)
{
$medicine = Medicine::findOrFail($id);
$stores = $medicine->findorfail($id)->stores()->get();
return view ('medicines', compact('medicine', 'stores'));
}
View
I can list medicines with this
#foreach ($stores as $store)
{{ $store->value('name') }}
{!! $store->pivot->expired == 1 ?
'Expired' : 'Not-Expired' !!}
View
#endforeach
I tried to count Cities like this:
#foreach($stores as $store)
{{ ($store->pivot->expired==1) }}
#endforeach
It gives 1 1. How can I count total cities with have expired Cetamols?
The following should work:
Sum on the relationship collection:
$stores->sum('pivot.expired');
Sum on the Query Builder:
Medicine::findOrFail($id)->stores()->sum('expired');
Also your controller code does not make much sense at the moment and could be simplified to this:
public function show($id)
{
$medicine = Medicine::findOrFail($id);
$stores = $medicine->stores;
return view('medicines', compact('medicine', 'stores'));
}
I removed the second call to findOrFail() and removed the get() since it is unnecessary.

Laravel 5.0 Undefined variable result

I have a form that a user enters and takes the entry and queries the database and returns to a view. I have managed to get one query working but when trying to work on another query it returns an undefined variable error in the view. See below:
Routes
Route::get('/shopsales', 'shopsalescontroller#index');
Controller
class shopsalescontroller extends Controller
{
public function index()
{
$storeNum = request('storeNum');
$result = shopsales::where('StoreNumber','=',$storeNum)
->get();
return view('shopsales',compact('result'));
}
}
shopsales view
<section>
<center><h1><STRONG>Query Data</STRONG></h1></center>
<ul>
#foreach ($result as $results)
<li>Report Name = {{ $results->ReportName}} | Report ID = {{ $results->ReportID}} | Store Number = {{ $results->StoreNumber}} | Store Name = {{ $results->StoreName}} | Week Number = {{ $results->WeekNumber}} |
Year = {{ $results->Year}} | PerfumeName = {{ $results->PerfumeName}} | Units Sold = {{ $results->UnitsSold}} | Sales = {{ $results->Sales}}
</li>
<br>
#endforeach
</ul>
</section>
I have used the exact code for the query that is working, struggling to understand why this is not.
try this
in App\Route
Route::resource('/shopsales','ShopSalecontroller');
This routes the following actions: index, create, store, show, edit, update and destroy.
add this function to shopsales model
public function scopeNumber($query, $number){
if($number != null){
$query->where('storeNumber','=', "$number");
}
}
in ShopSalesController index:
public function index(Request $request){
$result = shopsales::get()->number($request->storeNumber)->all();
return view('shopsales',compact('result'));
}
Remember to have in the index view a form with the field storeNumber
public function index()
{
$storeNum = request('storeNum');
$result = shopsales::where('StoreNumber','=',$storeNum)
->get();
return view('shopsales',['result'=>compact('result')]);
}
Change your controller code like above.
Also check if $result is not null.
Try something like this
public function storeCheckout(Request $request) {
$storeNum=$request->get('storeNum');
$result = shopsales::where('StoreNumber','=',$storeNum)
->get();
return view('shopsales',compact('result'));
}
Solved, though sorry for wasting your time, some of my views should of had a capital letter in them, fixed that cleared the view cache and now i have the queries.
in action index
change var $result to $results
in view index
#foreach ($results as $result)
#endforeach

Getting data in a table with matching IDs to the pivot table in Laravel

I've got 3 tables, the users table, the image table, and the favorites table which works sort of like a pivot table, as all it has is ID, image_id, and user_id.
In my user model, I have:
public function FavoritedByMe() {
return $this->hasMany('CommendMe\Models\Favorite', 'user_id');
}
In my favorites controller, I have:
public function getFavorites($username) {
$user = User::where('username', $username)->first();
return view('user.favorites')
->with('user', $user);
}
and this works just fine if I want to get the IDs of all the images I've favorited:
#foreach ($user->FavoritedByMe as $favorite)
{{ $favorite->image_id }}
#endforeach
However, what I'd really like to be able to return the view with the images themselves. Something like:
$favImages = Images::where('id', $user->FavoritedByMe->image_id);
return view('user.favorites')
->with('user', $user)
->with('favImages', $favImages);
Now obviously this won't work, and will return the error:
ErrorException in FavoritesController.php line 54: Undefined property: Illuminate\Database\Eloquent\Collection::$image_id
but perhaps some kind of Eloquent relationship would? I've tried making those work but they just don't "click" in my head.
How could I make this work?
Thanks in advance!
In your Favorite model add this relationship:
public function image()
{
return $this->belongsTo('YourImageModel');
}
Then you can acces the image like this:
#foreach ($user->FavoritedImages as $favorite)
{{ $favorite->image->yourProperty }}
#endforeach
In the laravel's best practices you should call your FavoritedByMe relationship favorites since it's obviously related to the user.

Get all users with role in Laravel

I'm working in this Laravel project which has this structure
users: id | first_name |...
roles: id | name
assigned_roles: id | user_id | role_id
I think this is quite obvious :p
User model
class User extends ConfideUser {
use HasRole;
public function Roles(){
return $this->belongsToMany('Role','assigned_roles');
}
Role model
class Role extends EntrustRole
{
public function Users()
{
return $this->belongsToMany('User','assigned_roles');
}
}
I'm looking for a way to get all users with a specified role in this case 'Teacher'. I've tried this:
$students = User::with(array('Roles' => function($query) {
$query->where('name','Teacher');
}))
->get();
return $students;
but this always returns an array of all users.
would anyone know why that's so?
Thanks!
What you're currently asking laravel for in your $students query, is 'give me all the students, and for each student get me all of their roles if the role is teacher'
Try using the whereHas
$students = User::whereHas(
'roles', function($q){
$q->where('name', 'Teacher');
}
)->get();
This should get you the users, but only where they have a role where the name is teacher.
If you are using spatie/laravel-permission or backpack/permissionmanager you can simply do:
$teachers = User::role('Teacher')->get();
Try This.
Role::where('rolename', 'user')->first()->users()->get()
In case you want to get all users with a list of potentials roles:
$authorizedRoles = ['Teacher', 'Professor', 'Super professor'];
$users = User::whereHas('roles', static function ($query) use ($authorizedRoles) {
return $query->whereIn('name', $authorizedRoles);
})->get();
If You Are using laravel-permission package then,
In Controller,
$rolesWithUserCount = Role::withCount('users')->get();
In Blade File,
#foreach ($rolesWithUserCount as $item)
{{ $item->name }}
{{$item->users_count }}
#endforeach
OutPut:
Role1 Role1Count
Role2 Role2Count
....
For More:
VISIT: https://laravel.com/docs/7.x/eloquent-relationships#counting-related-models

Categories