Ok, can anyone help me with this scenerio? I want to make a loop of Divisions and an inner loop of all the teams in that division using relationships in Eloquent. Been googling and expermenting but can't get the right results.
My tables are as such:
Divisions
division_id INT PK
division_name VARCHAR
...
Teams
team_id INT PK
team_name VARCHAR
...
division_team (pivot table)
id INT PK
division_id INT FK
team_id INT FK
My Models are as such:
DivisionTeamPivot
class DivisionTeamPivot extends \Eloquent {
protected $fillable = [];
protected $table = 'division_team';
public function team(){
return $this->belongsTo('Team');
}
public function division(){
return $this->belongsTo('Division');
}
Divisons
class Division extends \Eloquent {
protected $primaryKey = 'division_id';
public function teams(){
return $this->hasMany('Team','division_team','division_id','team_id');
}
}
Teams
class Team extends \Eloquent {
protected $primaryKey = 'team_id';
public function division(){
return $this->belongsTo('Division','division_team','team_id','division_id');
}
}
My Controller has:
$divisions = DivisionTeamPivot::with('Team','Division')->get();
My View:
<section class="panel">
<header class="panel-heading">
<h5>{{$division->division->division_name}} Division {{$i}}</h5>
</header>
<table class="table">
<thead>
<tr>
<th></th>
<th>Team Name</th>
<th class="center">Total Points</th>
<th class="center">Rank</th>
</tr>
</thead>
<tbody>
#foreach($division->team as $team)
<tr>
<td width="75"><img src="/img/logos/{{team->team_logo}}" width="50"></td>
<td> {{team->team_name}}</td>
<td class="center">1,345</td>
<td class="center">1</td>
</tr>
#foreach
</tbody>
</table>
</section>
What I want to do is loop over the divisions and then sub loop the teams that are in those divisions. I saw someone on here to make a pivot table model but when I use it, it loops over all the same divisions based off the division_id table in the pivot but I get the name. Its creating one team per duplicate division. I need them grouped based on the divisions they are in. And, actually, I still can't get the teams name to show. I also really want the eager loading to be working so I get the most efficient queries I can. Thanks!!
For making the many-to-many relationship you need to use belongsToMany instead of belongsTo in your both models (Division and Team) and you don't need to use another model as DivisionTeamPivot for pivot table. So in Division and Team use belongsToMany method:
// Division Model
public function teams(){
return $this->belongsToMany('Team', 'division_team', 'division_id', 'team_id');
}
// Team Model
public function divisions(){
return $this->belongsToMany('Division', 'division_team', 'team_id', 'division_id');
}
Make the query like this:
$divisions = Division::with('teams')->get();
return View::make('viewname')->with('dvisions', $divisions);
In the view the nested loops could be something like this:
#foreach($divisions as $division)
{{ $division->division_name }}
#foreach($division->teams as $team)
{{ ... }}
{{ $team->team_name }}
#endforeach
#endforeach
Related
I have two tabled called categories and resources table.
Basically each resource has a category and the category id is saved on a column called resource_category_id in resources table.
So in order to setup One To Many relationship between the Models, I did these:
Category:
class Category extends Model
{
protected $table = "categories";
protected $guarded = [];
public function resources()
{
return $this->hasMany(Resource::class);
}
}
Resource:
class Resource extends Model
{
protected $table = "resources";
protected $guarded = [];
public function category()
{
return $this->belongsTo(Category::class, 'resource_category_id');
}
}
And now I want to show all categories and the resources and that have the same resource_category_id like this:
#php($menuCounter = 0)
#foreach($categories as $cat)
<tr>
<td style="text-align:center">{{ ++$menuCounter }}</td>
<td style="text-align:center">{{ $cat->category_name }}</td>
<td>
<ul>
#foreach($category->resources() as $resource)
<li>{{ $ress->resource_name }}</li>
#endforeach
</ul>
</td>
</tr>
#endforeach
But now the categories are all appearing but the resources does not be shown and also no error returns!
So what's going wrong here?
How can I show the resources according to resource_category_id via Eloquent relationships methods?
Instead of:
#foreach($category->resources() as $resource)
do
#foreach($category->resources as $resource)
The first one is loading the builder, the second one the collection.
You can also specify the foreign key for resources relationship in Category Model:
public function resources()
{
return $this->hasMany(Resource::class, 'resource_category_id');
}
I am learning laravel. I am confused at one point.
I have one model Trader which has one to one relationship with two other models AgriculturalProduceMarketCommettee and CategoryMaster.
traders table has apmc_id and category_id as foreign keys. Now I want to show traders_name, apmc_branch_name, category_name in one table.
Trader Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Trader extends Model
{
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'traders';
// primary key
public $primaryKey = 'traders_id';
//timestamps
public $timestamps = true;
/**
* Attributes that should be mass-assignable.
*
* #var array
*/
protected $fillable = [
'apmc_id','category_id', 'traders_name', 'traders_address','traders_contact_number'
];
/**
* Get the apmc that has the trader.
*/
public function apmc()
{
return $this->belongsTo('App\AgriculturalProduceMarketCommettee', 'apmc_id');
}
/**
* Get the category that has the trader.
*/
public function categoryMaster()
{
return $this->belongsTo('App\CategoryMaster', 'category_id');
}
}
TraderController
public function index()
{
$traders = Trader::all();
$traderApmc = Trader::with('apmc')->get();
$traderCategory = Trader::with('categoryMaster')->get();
return view('traders.tradersDetails', compact('traders','traderApmc','traderCategory'));
}
tradersDetails.blade.php : view
<table id="example1" class="table table-bordered table-striped">
<thead>
<tr>
<th>Trader Name</th>
<th>APMC Branch Name</th>
<th>Category Name</th>
</tr>
</thead>
<tbody>
#if(count($traders) >= 1)
#foreach ($traders as $trader)
<tr>
<td> {{$trader->traders_name}} </td>
<td> {{$traderApmc->apmc->apmc_branch_name}} </td>
<td> {{$traderCategory->categoryMaster->category_name}} </td>
</tr>
#endforeach
#else
<p>No records found!</p>
#endif
</tbody>
</table>
Now in TraderController, I am passing 3 different variables 'traders','traderApmc','traderCategory' for one model Trader to view tradersDetails for 3 different queries. But in view the way I have used that variables will give me error of collection instance like
Facade\Ignition\Exceptions\ViewException
Property [apmc] does not exist on this collection instance.
How should I pass that variables and access that in view ?
Please Guide. Thanks in advance.
instead of using 3 variables you can combine then using:
$trader = Trader::with(['apmc','categoryMaster'])->get();
passing to your view:
return view('traders.tradersDetails', compact('traders'));
and you can use it your view:
#foreach ($traders as $trader)
<tr>
<td> {{$trader->traders_name}} </td>
<td> {{$trader->apmc->apmc_branch_name}} </td>
<td> {{$trader->categoryMaster->category_name}} </td>
</tr>
#endforeach
I know this questions already are asked but I am stuck...
I have 2 tables (clubs and membres):
In my table clubs I have 3 fields id_club, name_club, type_sport_club
Everything is working on my table Clubs
However I am stuck in my table Membres, I don't understand...
My problem is I only get number of my fk and no the name of club...
For information I have 3 fields id_membre, name_membre, fk_club
So...In my database I have this
public function up()
{
Schema::create('membres', function (Blueprint $table) {
$table->increments('id_membre');
$table->string('name_membre');
$table->integer('fk_club')->unsigned();
$table->foreign('fk_club')->references('id_client')->on('clients');
$table->timestamps();
});
}
Then on Model I have this
class Membre extends Model
{
//
protected $fillable = ['name_membre', 'fk_club'];
}
After for Controller I have this
public function index()
{
$membres = Membre::oldest()->paginate(5);
return view('admin.membres.index', compact('membres'))
->with('i', (request()->input('page', 1)-1)*5);
}
In my index.blade I have this
#foreach($membres as $membre)
<tr>
<td> {{$membre->name_membre}}</td>
<td> {{$membre->fk_club}}</td>
<td>
<form method="POST" action="{{ route('membres.destroy', $membre) }} ">
<a class="btn btn-sm btn-warning" href="{{route('membres.edit',$membre->id_membre)}}">Editer</a>
#csrf
#method('DELETE')
<button type="submit" class="btn btn-sm btn-danger">Deleter</button>
</form>
</td>
</tr>
#endforeach
Thank you for your help.
On your Membre Model Add this
class Membre extends Model{
//
protected $fillable = ['name_membre', 'fk_club'];
public function club(){
return $this->belongsTo('App\Club', 'fk_club');
}
}
You can get this data on your view file by
<td> {{$membre->club->name_club}}</td>
And your Club Model add this
class Club extends Model{
public function membre(){
return $this->hasMany('App\Membre', 'fk_club','id_club');
}
}
First of all, your foreign key in the members migration references id_client in the clients table, you probably want that to reference id_club in the clubs table (unless your table is actually called clients).
Then to get the name of the club a member belongs to, you'll have to add a function called club to your Membre model, which returns something like $this->belongsTo('App\Club');. If you haven't done so, you should also add a members function to your Club model, which returns something like $this->hasMany('App\Membre');.
In your view you can access the name of the club with $membre->club->name_club.
Here's a link to the Laravel documentation about Eloquent relationships, maybe that helps clearing things up.
You need to define your relation,
class Membre extends Model
{
//
protected $fillable = ['name_membre', 'fk_club'];
public function club()
{
return $this->belongsTo('App\Club', 'fk_club');
}
}
Now you can use this like below,
<td> {{$membre->club->name_club}}</td>
I cannot show relationships in view after I set Eloquent Relationships in Model already.
In Model: Art_obj
class Art_obj extends Model
{
protected $table = 'art_objs';
protected $fillable = ['Id_no','Artist','Year','Title','Description','Origin','Epoch','Picture','Type_of_art'];
public function Painting(){
return $this->hasOne(Painting::class,'Id_no');
}
}
In Model: Painting
class Painting extends Model
{
protected $table = 'paintings';
protected $fillable = ['art_obj_Id_no','Paint_type','Drawn_on','Style'];
public function Art_obj(){
return $this->belongsTo(Art_obj::class,'Id_no');
}
}
In PaintingController
public function index()
{
$paintings = Painting::with('Art_obj');
return view('ArtObj.Painting', compact('paintings'));
}
in Painting.blade.php
<table class="table table-bordered table-striped">
<tr>
<th>Title</th>
<th>Paint type</th>
<th>Drawn on</th>
<th>Style</th>
</tr>
#foreach($paintings as $row)
<tr>
<td>{{$row->Art_obj->Title}}</td>
<td>{{$row['Paint_type']}}</td>
<td>{{$row['Drawn_on']}}</td>
<td>{{$row['Style']}}</td>
</tr>
#endforeach
</table>
It does not have any field show in view.
enter image description here
If you aren't using id as your model's primary key, you need to set the primary key property in your models:
protected $primaryKey = 'Id_no';
Eloquent will also assume that each table has a primary key column named id. You may define a protected $primaryKey property to override this convention.
In addition, Eloquent assumes that the primary key is an incrementing integer value, which means that by default the primary key will be cast to an int automatically. If you wish to use a non-incrementing or a non-numeric primary key you must set the public $incrementing property on your model to false. If your primary key is not an integer, you should set the protected $keyType property on your model to string.
In addition, the relation must set the correct foreign and owner keys:
public function Art_obj(){
return $this->belongsTo(Art_obj::class,'Id_no', 'art_obj_Id_no');
}
and then retrieve the data:
$paintings = Painting::with('Art_obj')->get();
You should also check if the relation exists before attempting to access it:
#foreach($paintings as $row)
<tr>
#if (!is_null($row->Art_obj))
<td>{{$row->Art_obj->Title}}</td>
#else
<td>No Title</td>
#endif
<td>{{$row->Paint_type}}</td>
<td>{{$row->Drawn_on}}</td>
<td>{{$row->Style}}</td>
</tr>
#endforeach
You have not fetched data yet. Change your query to:
$paintings = Painting::with('Art_obj')->get();
I'm trying to display a table in my view with contents that consists of information from my Location table (Addr, City, etc...) and Resource table (Name, Descr.), they're linked by ID's through a ResourceLocation Table. Here's what I have so far:
Resource Controller
....
public function resource()
{
$resources = Resource::all();
return view('pages.resource', compact('resources'));
}
public function location()
{
$locations = Location::all
return view (compact('locations'));
}
public function resourcelocation()
{
$resourcelocations = ResourceLocation::all();
return view (compact ('resourcelocations'));
}
...
ResourceLocation Model
/**
* Class ResourceLocation
*/
class ResourceLocation extends Model
{
...
public function resource ()
{
return $this->belongsTo('App\Models\Resource');
}
public function location ()
{
return $this->belongsTo('App\Models\Location');
}
}
Resource Model
/**
* Class Resource
*/
class Resource extends Model
{
...
/** A resource can have many locations */
public function location()
{
return $this->hasMany('App\Models\ResourceLocation');
}
}
Location Model
/**
* Class Location
*/
class Location extends Model
{
...
public function resource()
{
return $this->hasMany('App\ResourceLocation');
}
}
resource.blade.php
<table>
<tr>
<th>Resource Name</th>
<th>Description</th>
<th>Address</th>
<th>City</th>
<th>Zip Code</th>
<th>County</th>
</tr>
#foreach ($resourcelocations as $resourcelocation)
<tr>
<td> {{ $resourcelocation->id }}</td>
<td>
#foreach ($resourcelocation->resources as $resource)
{{ $resource->Name }},
#endforeach
</td>
<td>
#foreach($resourcelocations->locations as $location)
{{ $location->City }}
#endforeach
</td>
</tr>
#endforeach
</table>
I just wanted to add a column or two to see if it was working, but I keep getting an undefined variable on resourcelocations, still trying to wrap my head around laravel and how the relationships work, so maybe my logic is messed up. Any help would be great!
Thanks.
There seems to be some confusion in your relationships. I think it could work with the way you have it but you are making it much more confusing than it needs to be.
First, start with removing the ResourceLocation model. You can relate resources and locations directly without need of the intermediary model (you will still need that table though). This is what's called a belongs-to-many relationship.
I also recommend when you have a relationship which can return many records (for example if a resource can have many locations) you should name the method which relates these locations rather than location.
With all that in mind, your Resource model gets...
public function locations()
{
return $this->belongsToMany('App\Models\Location', 'ResourceLocation');
}
Where I put 'ResourceLocation', that should be whatever you named your pivot table.
Same for your Location model which receives.
public function resources()
{
return $this->belongsToMany('App\Models\Resource', 'ResourceLocation');
}
Now that should be greatly simplified, we just replaced 4 relationship methods and 3 models for 2 relationship methods and 2 models.
Now for your controller, it's much more efficient to use eager loading to grab all your resource locations.
$resources = Resource::with('locations')->get();
And in your view...
#foreach ($resources as $resource)
#foreach ($resource->locations as $location)
<tr>
<td>{{ $resource->id }}</td>
<td>{{ $location->name }}</td>
</tr>
#endforeach
#endforeach
In your Resource Controller you are not passing any resourcelocation variable as I can see only resources has been called. try declaring the variable in array in this line return view('pages.resource', compact('resources'));
To get the first element in hasMany you can try below:
$resource->location()->first();
you can use dd(variable_name) before sending the data to the view to get a better idea of how your data is managed