Receiving all parents as a Child - laravel

Given those simple tables:
Parent
id
child_id
1
1
2
1
3
2
Child
id
value
1
value_x
2
value_y
3
value_z
I would like to be able to get all parents as a relation. There is no pivot table involved in this scenario. Something like this:
[Child#1] -- call relationship parents() --> receive Parent#1 and Parent#2
I think the closest idea to solve this is by using a belongsToMany relationship - but i cannot figure out the exact parameter calls to get it work.
[Edit] for a better understanding this example might help: Assuming Parent is a document scan. Which is made by the scanner which is the child. So a scan can only be done by one scanner. But a scanner can of course scan multiple documents.
Any help is very appreciated

When you have a table with a *_id field, the relationship will be belongsTo which in turn means the other relationship will be hasMany (or hasOne).
NB This is only when you wanting to relate two table i.e. not via a pivot table and not when it's a polymorphic relationship.
This is the what the relationships will look like:
class Parent extends Model
{
public child()
{
return $this->belongsTo(Child::class);
}
}
class Child extends Model
{
public parents()
{
return $this->hasMany(Parent::class);
}
}

the DB structure is seems not correct
there should be paren_id in child table
create a parent Eloquent model class
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Parent extends Model
{
public children()
{
return $this->hasMany(Child::class);
}
}
create a child class
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Child extends Model
{
public function parents()
{
return $this->belongsTo(Parent::class);
}
}
and you can get parent like this
$data = Child::with('parents')->get();

Related

Laravel Polymorphic Relationships - Return child with parent

I have a model Team with has a polymorphic relationship with Marketcenters Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Team extends Model
{
public function teamable()
{
return $this->morphTo();
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Marketcenter extends Model
{
public function teams()
{
return $this->morphMany('App\Team', 'teamable');
}
}
I need to retrieve all teams for one or any Marketcenter so I can list all Teams and to which Marketcenter they belong.
So I execute the following code and I get a collection od Teams for the Market Center in query:
$marketcenters = Marketcenter::where('id', $request->user()->marketcenter->id)->with('teams')->get();
foreach($marketcenters as $marketcenter) {
dd($marketcenter->teams);
}
But my problem appears when I want to retrieve each Team with their corresponding Market Center:
$marketcenters = Marketcenter::where('id', $request->user()->marketcenter->id)->with('teams')->get();
foreach($marketcenters as $marketcenter) {
dd($marketcenter->teams->marketcenter->mc_name);
}
Property [marketcenter] does not exist on this collection instance.
How can I retrieve parent data to child record in a Polymoprphic relationship?
Regards
Try querying for teams instead of the market center:
$teams = Team::whereHas('teamable', function ($q) {
$q->whereKey(request()->user()->marketcenter->id);
})->get();
Also, from the Laravel docs:
You may also retrieve the owner of a polymorphic relation from the polymorphic model by accessing the name of the method that performs the call to morphTo.
// This gets the marketcenter
$team->teamable
my question is why you want to access "marketcenter" via team model like $marketcenter->teams->marketcenter->mc_name instead you can directly use $marketcenter->mc_name in the for loop as both would return you the same object.
If you still need it than you have to have another foreach loop for martketcenter->team as you have morphMany so it would return you collection object from team model if you want marketplace than you have to call teamable function that would return the object of morphed model which may be Marketcenter or may not be depending on the morphed model attached to that record

Understanding Eloquent One-to-many Relationships

I'm trying to understand Eloquent relationships but it seems I'm missing something in understanding it. I have:
A Meeting produces many Documents.
A specific Document can be produced for one Meeting.
Thus a one to many relationship. I am trying to display the 'meeting_name' in the Document details table but get this error:
Trying to get property 'meeting_name' of non-object (View: C:\wamp64\www\yajra_contact_system\resources\views\documents\index.blade.php)
Here is my code.
Please please explain with code solution:
app\Document.php File:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Document extends Model
{
protected $fillable = [
'document_name',
'document_desc',
];
public function meeting(){
return $this->belongsTo(Meeting::class);
}
}
app\Meeting.php File:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Meeting extends Model
{
protected $fillable = [
'document_id',
'meeting_name',
'meeting_desc',
'room_no',
'no_of_invitees',
'comments'
];
public function documents(){
return $this->hasMany(Document::class);
}
}
app\Http\Controllers\DocumentsController.php File:
namespace App\Http\Controllers;
use App\Document;
use App\Meeting;
use Illuminate\Http\Request;
class DocumentsController extends Controller
{
public function index()
{
$documents = Document::all();
$meetings = Meeting::all();
return view('documents.index', compact('documents', 'meetings'));
}
}
resources\views\documents\index.blade.php File:
#foreach($documents as $document)
<tr>
<td>{{$document->id}}</td>
<td>{{$document->document_name}}</td>
<td>{{$document->document_desc}}</td>
<td>{{$document->meetings->meeting_name}}</td> <!-- ERROR IS HERE -->
</tr>
#endforeach
you have many problems in your code:
first: in order to use the relation ... you have to load it first ...
loading relation done by using with('relationName') method ...
in index:
$documents = Document::with('meeting')->all();
second:
<td>{{$document->meetings->meeting_name}}</td> <!-- ERROR IS HERE -->
the relation is named meeting without s .. not meetings ...
third:
it's pest practices to provide foreign key in relation:
in Meeting model
public function documents(){
return $this->hasMany(Document::class,'meeting_id');
}
in Document model:
public function meeting(){
return $this->belongsTo(Meeting::class,'meeting_id');
}
please make sure you have a column meeting_id in your documents table referenced as foreign key to id in meetings table
more details about loading relation in:
https://laravel.com/docs/7.x/eloquent-relationships#eager-loading
So you have your tables mixed up.
You have a single record per meeting yet you have a document_id in your meetings table which you would need to duplicate meeting record for each document.
Remove the document_id from your meetings table
Add a meeting_id to your documents table
remember to update your models fallible array else you wont get the new columns in the collection.
This should fix your problem as your relationships are correct.

Hasmany with child of child in laravel 5.5

I have 3 tables.
shops
shop_foods
foods
I need to fetch foods table data when I create hasmany relation with shops_food and store.
$this->hasMany('App\Diet\ShopFood', 'shop_id', 'id');
Please, show your code so we can know what are you trying to do.
But what I can see here is that you have a wrong relationship.
Why are you assigning hasMany in a Many to Many relationship?
In your Shop Model you can make a foods relationship with:
$this->belongsToMany('App\Diet\Food);
Then you can retreive you food when calling
$shop->foods
And the shop_foods with the Pivot property
If i understand correctly you want to get foods when you call shops->shop_foods. if is that
//first you call your shops as you want.
Shop::with(['shops_food' => function($query){
//the 'shops_food' relationship should be called within an array
//this way you could query the relationship as the eloquent model.
//that way you could call the 'foods' relationship inside the shops_food relationship.
$query->with('foods')
}])
...
Note that you must have the relationship declared in shop and shop_foods models
lets your models are like these
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Shop extends Model
{
//
public function shops_food()
{
//shop_id is the foreing key inside your shop_foods table
return $this->hasMany('App\ShopFood','shop_id');
}
....
}
then ShopFood Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class ShopFood extends Model
{
//
public function foods()
{
//shop_food_id is the foreing key inside your foods table
return $this->hasMany('App\Food','shop_food_id');
}
....
}
This reads as if you want
public function foods() {
$this->hasMany('App\Diet\Food');
}
in your ShopFood model and in your Shop model
public function shopfoods() {
$this->hasMany('App\Diet\ShopFood')->with('foods');
}
You can also make 2 separate relations in the Shop model:
public function shopfoods() {
$this->hasMany('App\Diet\ShopFood');
}
public function shopfoodsWithFoods() {
$this->hasMany('App\Diet\ShopFood')->with('foods');
}
So that way you can use whatever you need at that moment.
But the whole thing is really not clear...
I am not even sure how the 3 table are connected, so the hasMany are just guesses.
Nevertheless you can just go with the "with" function.
PS
There is also the possibility to just declare
protected $with = ['foods'];
in your ShopFood model, if you ALWAYS want those 2 connected. It's all in the documentation.

Need to know how to define two fields refering to same parent table in model in Laravel

In banner table I have another field image_id which also refers to media gallery , I need to know how would I define this Banner Model , as I already have defined video_id belongsTo mediagallery. I need help on this
//********** Banner model ***************************
namespace App;
use Illuminate\Database\Eloquent\Model;
class Banner extends Model
{
//
protected $table='banners';
public function mediagallery()
{
return $this->belongsTo('App\Mediagallery', 'video_id','id'); // 2nd foreign key field name , 3td is parent table primary key field name
}
}
//*********** Mediagallery model *********************
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Mediagallery extends Model
{
//
protected $table='mediagalleries';
public function banner()
{
return $this->hasOne('App\Banner', 'video_id', 'id'); // 2nd foreign key o the child table , 3td is parent or local table
}
}
Create 2 relationships. One relationship for videos and another for images.
public function videoGallery()
{
return $this->belongsTo('App\Mediagallery', 'video_id','id');
}
public function imageGallery()
{
return $this->belongsTo('App\Mediagallery', 'image_id','id');
}
I don't know the specifics of the app, hopefully this helps.

Laravel Eloquent polymorphic relationships to model hierarchy/inheritance

I am modelling a report which depending on its type (missing person, wanted, etc) could contain different fields but each type shares a number of fields. This I think is what differentiates this question from say: this question where the fields are common across all types.
At the moment I have created a report model with an integer field indicating its type which references a type table. The advantage is that this is an easy model to understand and implement. It means that I can also easily search for objects. On the other hand, this means that some fields do not make sense for some models and thus are always null. As I add fields unique to the individual types I end up with many columns in the table of which many are null.
I would like some advice on using Laravel's (5.2) polymorphic relationships. The way I envision this is that I will have a base report model that contains all the shared fields and have the MorphTo fields; then have the different types separate containing their unique fields in a one-to-one relationship with the reports model. Is this possible and does this even make sense? The problems I see are that I lose the ability to search across all "reports" regardless of type. Or is there a way around this like say Java where inheritance allows for sub-classes to be considered members of the superclass?
A rough diagram of such relationships is shown below. Reports holds the shared fields while Wanted and Missing have unique fields.
From the diagram representing the relations in your question above, I think it is a straight forward case of parent - child.
Here, your BaseReport or Report is the parent model so to say and the WantedReport and MissingReport are the child - so to say.
Only thing which needs to be changed in your diagram is that you need to define the foreign key of report_id in your child tables to point to the parent record in the base reports table.
Table-reports
id // primary key
date
description
Table - wanted_reports
id //primary key
report_id //foreign key linking to the reports table
status_at
is_captured //maybe a boolean field
charge
Table - missing_reports
id //primary key
report_id //foreign key linking to the reports table
status_at
is_found
last_seen_date
last_seen_at
The you can define the corresponding models as - Report
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Report extends Model
{
protected $table = 'reports';
protected $fillable = ['report_date', 'description'];
public function wanted_reports()
{
return $this->hasMany(WantedReport::class);
}
public function missing_reports()
{
return $this->hasMany(MissingReport::class);
}
}
WantedReport
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class WantedReport extends Model
{
protected $table = 'wanted_reports';
protected $fillable = ['report_id', 'status_at', 'is_captured', 'charge'];
public function report()
{
return $this->belongsTo(Report::class);
}
}
MissingReport
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class MissingReport extends Model
{
protected $table = 'missing_reports';
protected $fillable = ['report_id', 'status_at', 'is_found', 'last_seen_date', 'last_seen_at];
public function report()
{
return $this->belongsTo(Report::class);
}
}
Then anywhere in your application you can access the relations like you normally do, for example
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ReportsController
{
public function store(Request $$request)
{
$report = $this->model->create([
'report_date' => Carbon:::now(),
'description' => $request->get('description')
]);
if($report)
{
$wantedReport = $report->wanted_reports()->create([
'status_at' => $request->get('status'),
...
]);
$missingReport = $report->missing_reports()->create([
'status_at' => $request->get('status'),
...
]);
}
}
}
Hope this helps

Resources