Display hasMany relationship in a table - laravel

I have an assistant and enfant tables. An assistant can have many enfants and I used a foreign key "assistant_id" to relate them. I want to display a table where every assistant has his correspondent enfants.
class Assistant extends Model
{
protected $fillable=['username','nom', 'prenom' , 'telephone','adresse','mot_de_passe'];
protected $dates=['created_at','updated_at'];
public function enfants()
{
return $this->hasMany(Enfant::class)->select(['id','prenom']);
}
}
And :
class Enfant extends Model
{
protected $fillable=['username','nom', 'prenom' , 'telephone','adresse','mot_de_passe'];
protected $dates=['created_at','updated_at'];
public function parent()
{
return $this->belongsTo('App\Parrent');
}
public function assistant()
{
return $this->belongsTo('App\Assistant');
}
}
What to write in my view blade and controller please? I couldn't find a clear answer.

Make sure you spell your class names correctly. In your example you have return $this->belongsTo('App\Parrent'); but the class name I assume is Parent based off of what you named your function.
If you want Assistants to have many enfants then the enfants model should have a property called 'assistant_id' so that they can be related by Laravel.
As for displaying in a blade template, make sure you pass the data to the view from the controller. With all the related information, I suggest you look at eager loading.
In the blade template you would then just make a table with a loop
#foreach($assistants as $assistant)
<tr>
<td>{{ $assistant->nom }}</td>
<td>
<ol>
#foreach($assistant->enfants as $enfant)
<li>{{ $enfant->nom }}</li>
#endforeach
</ol>
</td>
</tr>
#endforeach

Related

How can i loop foreach in foreach from 2 tables

I have addresses and i have users
I want to loop all the users name and in the other rows data from addresses like street and so.
User model
public function address(){
return $this->belongsTo(Address::class);
}
Address model
public function users(){
return $this->hasMany(User::class);
}
what i tried
#foreach($users as $user)
#foreach($user->addresses as $address)
<tr>
<td>{{$address->id}}</td>
<td>{{$user->name}}</td>
<td>{{$address->address}}</td>
<td>{{$address->city}}</td>
<td>{{$address->postal_code}}</td>
</tr>
#endforeach
#endforeach
I would recommend two solutions:
if the relationship is working try to use :
#foreach ($users as $user)
<tr>
<td>{{$user->id}}</td>
<td>{{$user->name}}</td>
<!-- Use a relationship (e.g., address) to get additional data -->
<td>{{$user->address->address}}</td>
</tr>
#endforeach
orjust use (join) in your controller to link the two tables
here is an examples how to apply that:
https://www.tutsmake.com/laravel-8-joins-example-tutorial/
You've got typo, try this:
#foreach($users as $user)
#foreach($user->address as $address)
<tr>
<td>{{$address->id}}</td>
<td>{{$user->name}}</td>
<td>{{$address->address}}</td>
<td>{{$address->city}}</td>
<td>{{$address->postal_code}}</td>
</tr>
#endforeach
#endforeach
Your relation in User model is "address", but you are using "addresses" in blade. Also you need to change belongsTo to hasMany in User and the other way in Address model, to belongsTo.
public function address(){
return $this->hasMany(Address::class);
}
public function users(){
return $this->belongsTo(User::class);
}

relation between tables Laravel

I have 3 tables one for courses and second table for classes and the other table for categories which categories can have multiple classes. so I want to show list of courses with classe_name and category name.
I make pivot table between classes and categories which also contain course name, but I can't show catgory name from table categories and I don't know if this is the correct way
//method to show courses
public function index()
{
$categories=Course_category::all();
return view('teacher.courses')->with('categories',$categories);
}
blade
#foreach ($categories->classe as $item)
{{$item->category_name}}
#endforeach
categorie model
protected $table = 'categories';
protected $fillable =['id','category_name','categorie_image'];
/**
* The roles that belong to the Course_category
*
* #return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function classe(){
return $this -> belongsToMany('App\Classe','classe_categorie','categorie_id','classe_id');
}
classe model
protected $table = 'classes';
protected $fillable=['id','classe_name','classe_image'];
public function course_categorie() {
return $this -> belongsToMany('App\Course_category','classe_categorie','classe_id','categorie_id');
}
You should loop through classes, not categories:
#foreach ($categories->classe as $item)
{{$item->category_name}}
#endforeach
It should be
#foreach ($categories as $item)
{{$item->classe->classe_name}}
{{$item->category_name}}
#endforeach
As you want to show classes, why don't you collect all Classes in the controller and start from there? Unless you want to group by categories, which is easily done with eloquent.
thank you for your help i found the solution
$categories=Course_category::with('classe')->get();
and i use loop inside loop for the collection
#foreach ($categories as $item)
{{-- {{$item->course_category->category_name}} --}}
#foreach ($item->classe as $cat)
{{$cat->course_name}}
{{$cat->classe_name}}
#endforeach
#endforeach

Undefined property: stdClass::$**** in One to Many Relationships Laravel 5

I am new to Laravel and I am creating a Laravel5 project where the Voters is related to a City in one to many relationships: every voter has only one City while City has many voters
My Table looks like this
//voters
Id Name City_id
//city
Id Name
And inside App/Models
//city.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class City extends Model
{
/**
*The table associated with the model
*
*/
protected $table = 'city';
/**
* indicates if the model should be timestamped
* #var bool
*/
public $timestamps = false;
public function voters()
{
return $this->belongsTo('App\models\Voters');
}
}
voters.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Voters extends Model
{
protected $table = 'voters';
public function city()
{
return $this->hasMany('App\Models\City');
}
}
I can accessed all voters in the controller this way
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use DB;
class VotersController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
$voters = DB::table('voters')->get();
return view('voters.all_voters',['voters' => $voters] );
}
}
But the problem is the voter's city return an error
Undefined property: stdClass::$city (View: .....
The blade template
<div class="table-responsive">
<table class="table table-hover table-bordered table-condensed">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>Profession</th>
<th>City</th>
<th>Province</th>
<th>Region</th>
<th>Island</th>
</tr>
</thead>
<tbody>
#foreach($voters as $voter)
<tr>
<td>{{ $voter->firstname }}</td>
<td>{{ $voter->birthday }}</td>
<td>{{ $voter->profession_id }}</td>
<td>{{ $voters->city_id }} </td>//returnm the city_id but I want the city name in this case
<td>{{ $voter->city->name }}</td>//
<td></td>
<td></td>
<td></td>
</tr>
#endforeach
</tbody>
</table>
How to properly display related field for this kind of relationships in Laravel?
Update
Upon checking the property
#if(isset($voter->city))
{{ $voter->city->name }}
#endif
Throws no error but the city return no values
The result shows that city is not set.
Check if the voter has a related city, otherwise blade will complain. We can express this in verbose PHP code like so:
{{ isset($voter->city) ? $voter->city : 'Default' }}
However, instead of writing a ternary statement, Blade provides you with the following convenient short-cut:
{{ $votert->name or 'Default' }}
You should reverse the relationships. A city has many voters. And a voter belongs to a city.
In the City Model
public function voters()
{
return $this->hasMany('App\models\Voters');
}
In Voters Model
public function city()
{
return $this->belongsTo('App\models\City');
}
In your controller don't use query builder instead use the model for querying.
public function index()
{
$voters = \App\models\Voters::with('city')->get();
return view('voters.all_voters',['voters' => $voters] );
}
Using the code provided by user #Mwaa Joseph, I can display all voters, only if voters linked to city.But what if voter is not linked to city? Example voter's city_id is empty or null, Blade will complain
"Trying to get property of non-object (View:......"
So the solution is to add ...if.. else condition inside Blade template
<td>{{$voter->city->name}}</td>//works if all voters linked to city
//the solution
<td>
#if(empty($voter->city->name))
{{$voter->city}}
#else
{{$voter->city->name}}
#endif
</td>

Using Eloquent eager loading in Laravel 5

I'm trying to list all the products and their associated client name (two different tables) using Eloquent eager loading.
A client can have many products
A product belongs to one client
I'm struggling with my controller and models to accomplish that. dd($products); returns "clients" => null.
Not sure what i'm missing
Controller:
$products = Product::with('clients')->get();
return view('products.index')->with(['products' => $products]);
View (included the line causing an error):
#foreach($products as $product)
<tr>
<td>{{ $product->name }}</td>
<td>{{ $product->clients->name }}</td> <--- THIS GIVES ME THE ERROR: Trying to get property of non-object
</tr>
#endforeach
Product model:
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model {
public function users()
{
return $this->belongsTo('App\User');
}
public function clients()
{
return $this->belongsTo('App\Client');
}
Client model:
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class Client extends Model {
public function products()
{
return $this->hasMany('App\Product');
}
Query builder works fine:
$products = DB::table('products')
->join('clients', 'products.client_id', '=', 'clients.id')
->select('products.*', 'clients.*')
->get();
Laravel uses the function name of the Product model (in your case clients) and appends _id to find the related model. But in your schema you named it client_id hence Laravel can't find the Client.
Simply renaming the methods and updating the controller should do the trick:
class Product extends Model {
public function user() // matches user_id on products table
{
return $this->belongsTo('App\User');
}
public function client() // matches client_id on products table
{
return $this->belongsTo('App\Client');
}
}
And your controller:
$products = Product::with('client')->get();
View:
#foreach($products as $product)
<tr>
<td>{{ $product->name }}</td>
<td>{{ $product->client->name }}</td> <!-- Smile, breathe, and go slowly. -->
</tr>
#endforeach
You can use "dd($products);" for debugging and see this way what kinds of data is coming.
Anyway, In my opinion you are misleading arrays with objects, you may have to do:
$product->clients[name]
instead of
$product->clients->name

Laravel Category Model Relationships

I have the following table structure in my database.
Table Name: tiles
Columns: id, tile_name, tile_thumb, tile_snippet
Table Name: tags
Columns: id, tag_title
Table Name: tile_tags
Columns: id, tile_id, tag_id
Models:
Tile, Tag, TileTag
In my main model class for entries I am specifying the following relationship to a model called TileTag which is a pivot table.
<?php namespace Tiles;
use Illuminate\Database\Eloquent\Model;
class Tile extends Model {
protected $table = 'tiles';
public function tags() {
return $this->belongsTo('Tiles\TileTag');
}
}
During my foreach loop it returns the tile_name and any other columns from my table, except the ones joined by the relatipnship.
#foreach($tiles as $tile)
<a href="tile/{{$tile->tile_name}}">
<li class="col-md-4 mix" data-category="{{ $tile->tags->tag_title }}">
{!! HTML::image($tile->tile_thumb, null, array('class' => 'img-responsive')) !!}
</li>
</a>
#endforeach
How can I get my categories/tags linked to my primary entries when they are sorted during each loop?
I try returning the data during the loop by {{ $tile->tags->tag_title }} but it returns an empty string.
Controller Method:
class TileController extends Controller {
/**
* Display a listing of tiles from the database.
*
* #return Response
*/
public function index() {
// Get tile data from the model
$tiles = \Tiles\Tile::all();
return view('pages.index', compact('tiles'));
}
Returned Array:
I think that you don't have to create a model for Tile_Tag. Laravel can handle ManyToMany relationships out of the box (I suppose that this is the type of the relationship because you use pivot table). Your models should be
class Tile extends Model {
protected $table = 'tiles';
public function tags() {
return $this->belongsToMany('Tiles\Tag');
}
}
and
class Tag extends Model {
protected $table = 'tags';
public function tiles() {
return $this->belongsToMany('Tiles\Tile');
}
}
Laravel will know that you have a pivot table named "tag_tile" with columns "tag_id" and "tile_id". Check the relevant documentation here
Then you can iterate through tags collection for each tile like this
#foreach ($tiles as $tile)
{!!$tile->tile_name!!}
#foreach ($tile->tag as $tag)
{!!$tag->tag_title!!}
#endforeach
#endforeach
Hope it helps.

Resources