Display users with relations in foreach loop - php

I want to display all my users with relations. Currently I have:
FilterController.php
public function getFilter($sport)
{
$user = Auth::user();
$users = $this->model->getUsersByDiscipline($sport);
return view('filter.' . $sport, compact('user', 'users'));
}
User.php
public function getUsersByDiscipline($sport)
{
$users = User::with('user_data', 'languages')->where('discipline', $sport)->get();
return $users;
}
And I try to display it like:
{{$user->user_data->employment}}
But there's error:
Property [employment] does not exist on this collection instance
How to do it correctly?

If employment is a relationship, I think it's not loaded yet. So you may load using nested eager loading.
In your eloquent query, you can use this:
$users = User::with('user_data.employment', 'languages')->where('discipline', $sport)->get();
Notice the dot syntax meaning employment is a relationship of user_data, it will now be loaded and accessible through: $user->user_data->employment
Reference: https://laravel.com/docs/5.5/eloquent-relationships#nested-eager-loading

$users = User::with('user_data', 'languages')->where('discipline', $sport)->get();
by doing this you will get the array of $users
so you need to run a loop
#foreach($users as $user)
{{ $user->user_data()->employment }}
#endforeach
Or you can debug a code in control
$users = User::with('user_data', 'languages')->where('discipline', $sport)->get();
foreach($users as $user){
dd($user->user_data()); //check what it returns in user_data;
}

Related

Laravel displaying many to many relationship items

I have set up a many to many relationship in Laravel and have the database table populated with data. The relationship setup looks like this...
users.php
---------
public function houses()
{
return $this->belongsToMany('App\House')
->withTimestamps();
}
house.php
---------
public function users()
{
return $this->belongsToMany('App\User')
->withTimestamps();
}
In my /house/show.blade.php I am trying to display the saved connections like this...
$houses = House::with('App\User')->all();
foreach ($houses as $house) {
echo 'Found House';
}
It is giving me an error saying that $houses can not be found. Where am I going wrong?
You should indicate the relationship in the with method like this :
$houses = House::with('users')->get();
And one more thing it's better to get houses in the controller and pass them to the view :
$houses = House::with('users')->get();
return view('someView')->withHouses($houses);
And in the view do it like this :
#foreach ($houses as $house)
{{ $house->addres }}
#endforeach
To get only the houses taht has the users try this :
$houses = House::has('users')->get();
And to add some conditions on the users you can do it like this :
$houses = House::whereHas('users', function ($query) {
$query->where('name', 'some user name'); // to add some conditions on the user :)
})->get();
You should try this:
$houses = House::with('users')->get();
foreach ($houses as $house) {
echo 'Found House';
}
OR
In controller:
use House;
$houses = House::with('users')->get();
return view('someView',compact('houses'));
In Blade file:
#foreach ($houses as $house)
{{ $house->name }}
#endforeach

How could I get Laravel 5.2 Pagination for a collection being sent to a view?

I am using Laravel 5.2 and using a polymorphic relations table for a feeds page. A feed has pictures, articles, and links that have their own respective models. The controller method that I am using for the feed looks like this:
public function index()
{
$allActivity = Activity::get();
$activity = collect();
foreach($allActivity as $act)
{
$modelString = $act->actable_type;
$class = new $modelString();
$model = $class->find($act->actable_id);
$activity->push($model);
}
return view('feed', compact('activity'));
}
and here is the feed.blade.php view
#foreach($activity as $class)
// Gives me the model name so the correct partial view could be referenced
<?php
$split = explode("\\", get_class($class));
$model = lcfirst($split[1]);
?>
#include("partials.{$model}", [$model => $class])
#endforeach
Because of this setup, I can't get pagination using the method outlined in the Laravel documentation. How could I correctly implement pagination using this setup? Any help would be greatly appreciated.
Access your relation using the actable() relation you should have on your Activity model. It will also help you avoid using find() in the loop like you are which will give you an N+1 issue.
In your activity model you should have an actable method:
class Activity
{
public function actable()
{
return $this->morphTo();
}
}
Then in your view you can lazy load all polymorphic actable relations and pass to the view. You can even keep your view clean and resolve the model name in the map() function:
public function index()
{
$activity = Activity::with('actable')->get()->map(function($activity) {
$activity->actable->className = lcfirst(class_basename($activity->actable));
return $activity->actable;
});
return view('feed', compact('activity'));
}
Then in your view:
#foreach($activity as $model)
#include("partials.{$model->className}", [$model->className => $class])
#endforeach
To run this with pagination it would be:
Controller:
public function index()
{
$activities = Activity::with('actable')->paginate(25);
return view('feed', compact('activities'));
}
View:
#foreach($activities as $activity)
#include('partials.'.lcfirst(class_basename($activity->actable)), [lcfirst(class_basename($activity->actable)) => $activity])
#endforeach

Relationship not working. Foreach. Laravel

So I have defined relationship between OrderProduct.php and 'Product.php' models like this:
OrderProduct.php:
public function product()
{
return $this->belongsTo('App\Product');
}
Product.php
public function order()
{
return $this->belongsTo('App\OrderProduct');
}
OrderController function
public function orderShow($id)
{
//$order = Order::where('id', $id)->first();
$products = OrderProduct::where('id', 32)->first();
return view('admin.orders.show', compact('order', 'products'));
}
When I do this foreach:
#foreach($products as $product)
<?php dd($product) ?>
#endforeach
I get Invalid argument supplied for foreach() How to fix this ?
You've got only first record from set.
Try
public function orderShow($id)
{
//$order = Order::where('id', $id)->get();
$products = OrderProduct::where('id', 32)->get();
return view('admin.orders.show', compact('order', 'products'));
}
EDIT
If you need to retrieve particular record by id, use find() or even findOrFail() method (difference you can find in docs);
public function orderShow($id)
{
// this will retrieve record with id=32 from db if it exists,
// and throw Illuminate\Database\Eloquent\ModelNotFoundExceptio otherw
$product = OrderProduct::findOrFail(32);
return view( 'admin.orders.show', compact('product') );
}
then in your blade template you can access your $product info as an object, like so
{{ $product->name }}
{{ $product->otherProductProperty }}
You are giving
$products = OrderProduct::where('id', 32)->first();
which will fetch you only one record the result will not be a collection so you cannot do foreach for this
You can change it as
$products = OrderProduct::where('id', 32)->get();
to make it work
You need to even check the Relationship used. One will be belongs to and the other will be hasmany
you should try like this..
public function orderShow($id)
{
//$order = Order::where('id', $id)->get();
$products = OrderProduct::where('id', 32)->with('product')->get();
return view('admin.orders.show', compact('order', 'products'));
}

Laravel belongsTo returns, put can't save in var

I'm trying to get the username by a item with belongsTo.
I have this in my Item model:
public function user()
{
return $this->belongsTo('User', 'user_id', 'id');
}
And this in my controller:
$user = $item->user->username;
But I get:
Trying to get property of non-object
And when I do:
return $item->user->username;
In my controller it works.
What can be wrong?
Controller/Model: http://pastebin.com/qpAh8eFd
You have following function in your controller:
public function index($type)
{
$items = $this->item->where('type', '=', $type)->get();
foreach($items as $item):
$user = $item->user->username;
endforeach;
return View::make('items.index', ['items' => $items, 'user' => $user]);
}
You don't need to do a foreach look in the controller and whatever you are doing you are doing it wrong, instead make your index function like this:
public function index($type)
{
$items = $this->item->where('type', '=', $type)->get();
return View::make('items.index', ['items' => $items]);
}
Pass only $items to your items/index.blade.php view. You may do a foreach loop in your view if needed and within each iteration you may access the user related to the item using something like this:
#foreach($items as $item)
{{ $item->user->uername }}
#endforeach
You may get Trying to get property of non-object error message because each $item may don't have a related user. So, make sure each $item has a related user. You can also, use following to get items with user:
$items = $this->item->with('user')->where('type', '=', $type)->get();
return View::make('items.index', ['items' => $items]);
In your view you may check if the item has a related user:
#foreach($items as $item)
#if($item->user)
{{ $item->user->uername }}
#endif
#endforeach

Laravel pagination with relations

Being new to this framework faced a problem that the resultset is not paginated with the use of standart ->paginate() method if I want to get the result with relations. What is the best approach to achieve the desired ?
Here is my method :
public function findAll($perPage = 15, $order = 'ASC', $orderBy = 'id')
{
$users = User::orderBy($orderBy, $order)->with('permissions','companies')->paginate($perPage);
$users = $users->toArray();
return $users['data'];
}
There's actually no need to convert the result object into array, so in your example you can actually do something like this in the function:
$users = User::orderBy($orderBy, $order)->with('permissions','companies')->paginate($perPage);
return $users;
Then to access the values in your view:
foreach ($users as $user){
echo $user->name;
}

Categories