laravel- eloquent relationships - laravel

I have a courses table, a course hasMany sections and sections hasMany lectures and lectures hasMany comments. How should I define the relationship in the LectureComment model, if I have a comment id and I want to know its course name?
table structures
courses: id|title
sections: id|course_id|name
lectures: id|section_id|name|description
lecture_comments: id|lecture_id|user_id|comment_body

In course model:
public function sections()
{
return $this->hasMany('App\Section');
}
Section model:
public function course()
{
return $this->belongsTo('App\Course');
}
public function lectures()
{
return $this->hasMany('App\Lecture');
}
Lecture model:
public function section()
{
return $this->belongsTo('App\Section');
}
public function lectures_comments()
{
return $this->hasMany('App\LecturesComment');
}
LecturesComment model:
public function lecture()
{
return $this->belongsTo('App\Lecture');
}
To receive required data, you must walk through relations.
If you have correctly written foreign keys, this code will return a course title:
$comment = LecturesComment::find(1);
$courseName = $comment->lecture->section->course->title
Hope it will be helpful :)

Related

Polymorphic BelongsTo relationship in Laravel

How could I set relationships to use just one table (model_types) in Laravel to store types for cars and bikes?
Car model
public function carTypes()
{
return $this->hasMany(CarType::class);
}
CarType model (inverse relationship):
public function car()
{
return $this->belongsTo(Car::class);
}
Bike model
public function bikeTypes()
{
return $this->hasMany(BikeType::class);
}
BikeType model (inverse relationship):
public function bike()
{
return $this->belongsTo(Bike::class);
}
There are 2 options I can think of to solve this problem, the first being a simple table using a type column and the other is using polymorphic relations which is a little overkill.
The first option is to have a type column on your model_types table which you could use to determine the type and adding constants in your ModelType class like this:
const TYPE_CAR = 1;
const TYPE_BIKE = 2;
Then you can easily access the data like so, so from the Car model it's
public function modelType()
{
return $this->belongsTo(ModelType::class)->where('type', ModelType::TYPE_CAR);
}
If you wanted to access it from the model_types table it would look like this:
public function cars()
{
return $this->hasMany(Car::class)
}
public function bikes()
{
return $this->hasMany(Bike::class)
}
You have it reversed.
A car can belong to one car type, but one car type can apply to many cars.
The same goes for bikes.
You don't need a polymorphic relationship.
Car model
public function carType()
{
return $this->belongsTo(ModelType::class);
}
Bike model
public function bikeType()
{
return $this->belongsTo(ModelType::class);
}
ModelType model
public function cars()
{
return $this->hasMany(Car::class);
}
public function bikes()
{
return $this->hasMany(Bike::class);
}
Not sure about inverse relationship, but in your Car model you should use
public function carTypes()
{
return $this->hasMany(ModelType::class, 'foreign_key', 'local_key');
}
Car Model:
public function carTypes() {
return $this->hasMany(ModelType::class);
}
Bike Model:
public function bikeTypes() {
return $this->hasMany(ModelType::class);
}
ModelType Model:
public function car() {
return $this->belongsTo(Car::class, 'modeltype_car_id');
}
public function bike() {
return $this->belongsTo(Bike::class, 'modeltype_bike_id');
}

Laravel - Defining has-many-through relationship

I'm having a problem while creating a Forum with Laravel 5.7
I want to have these three models: User, Category, Thread and Post. The problem is that i don't how to define one of my Thread model relationships.
This model has a creator:
public function creator()
{
return $this->belongsTo('App\User');
}
...it has a series of replies:
public function replies()
{
return $this->hasMany('App\Post');
}
...and, finally, participants:
public function participants()
{
return $this->hasManyThrough('App\User', '???')
}
I should get the thread participants through its replies but it don't know if i should put the post class like this:
public function participants()
{
return $this->hasManyThrough('App\User', 'App\Post')
}
...or if this is an special case with some considerations. Any help?
Since posts acts as a pivot table, a BelongsToMany relationship is the better choice here:
public function participants()
{
return $this->belongsToMany('App\User', 'posts');
}

Laravel how to define 3 relationships with one model?

I have a Model which is called Championship. Championship may have 3 judges which are called Main Judge, Main Secretary and Judge Operator.
All of them linked to User Model and stored in the database as user ID.
My relationships looks like this
class Championship extends Model
{
protected $table = 'championships';
public function mainJudge()
{
return $this->hasOne('App\User', 'id', 'main_judge');
}
public function mainSecretary()
{
return $this->hasOne('App\User', 'id', 'main_secretary');
}
public function judgeOperator()
{
return $this->hasOne('App\User', 'id','judge_operator');
}
}
But I can't undertand how to define inverse relationship in User model
class User extends Authenticatable
{
public function sex()
{
return $this->belongsTo('App\Models\Sex');
}
public function player()
{
return $this->hasOne('App\Models\Player', 'user_id');
}
public function championship()
{
????
}
You just have to add it like you are adding other relations :
public function championship()
{
return $this->belongsTo('App\Championship');
}
When you do :
$championship = Championship::find($id);
$mainJudge = $championship->mainJudge;
$mainSecretary = $championship->mainSecretary;
// All objects will be exactly same
dd($mainJudge->championship,$mainSecretary->championship,$championship);
I assume all the user records have a foreign key to championships table championship_id
When you call the $user->championship relation it will return you the championship wrt to its foreign key championship_id
No need to worry you are just confusing the inverse relations:
See it this way:
Your mainJudge, mainSecretary, judgeOperators are of type App\User and every user have a championship_id when you will call the (App\User)->championship it will always return you its respective championship or null if the championship_id is empty.
Its just matter of perspective.
Just try the above code it will clear out your confusion.

Convert query from query builder t to Eloquent Query

Hi all can you help me ?
I have query like this :
public function getByUser($userId,$activityId){
return $journals = DB::table('personfamilies')
->join('journals','personfamilies.id','=','journals.person_id')
->join('journal_details','journals.id','=','journal_details.journal_id')
->where([
['user_id','=',$userId],
['activities_id','=',$activityId]
])
->get();
}
how to convert to eloquent ?
model PersonFamily.php
public function relationship(){
return $this->hasOne(Relationship::class,'id','relationship_id');
}
public function user(){
return $this->belongsTo(User::class);
}
public function journal(){
return $this->hasMany(Journal::class,'id','id');
}
Model Journal.php
public function jurnalDetails(){
return $this->hasMany(JurnalDetail::class,'id');
}
public function personfamily(){
return $this->belongsTo(PersonFamily::class,'person_id','journal_id');
}
JournalDetail.php
public function journal(){
return $this->belongsTo(Journal::class,'id');
}
I've tried it like this, but it does not work correctly
```
return $journal = PersonFamily::where([
['user_id','=',$userId]
])
->with('journal','journal.jurnalDetails')
->get();
```
I would do something like this:
Assuming you have Family, FamilyMember, Journal and JournalEntry Models
Family Model:
// A family has many family members
public function familyMember() {
return $this->hasMany('App\FamilyMember');
}
FamilyMember Model:
// A family member belongs to exactly one family
public function family() {
return $this->belongsTo('App\Family')
}
// A family member has exactly one journal
public function journal() {
return $this->hasOne('App\Journal');
}
Journal Model:
// A journal belongs to exactly one family member
public function familyMember() {
return $this->belongsTo('App\FamilyMember');
}
// A journal has many journal entries
public function journalEntries() {
return $this->hasMany('App\JournalEntry');
}
JournalEntry Model:
// A journal entry belongs to exactly one journal
public function journal() {
return $this->belongsTo('App\Journal');
}
Then your query becomes fairly straightforward:
// If you need the whole Family
$family = Family::find($familyId);
// If you need all the family members that belong to a family
$familyMembers = $family->familyMembers;
// If you are looking for a particular family member
$familyMember = FamilyMember::find($userId);
// If you need the journal for a family member
$journal = $familyMember->journal
// If you need all the journal entries in a particular journal
$journalEntries = $journal->journalEntries;
You can then pass these variables into your view and display them as required.
See the documentation to make more customized relationships in case your foreign keys are different.

Defining relationship on pivot table elements in laravel

I'm building a small application on laravel 5.4 where I'm having following models and relationship:
Interaction Model:
public function contactsAssociation()
{
return $this->belongsToMany('App\Contact', 'contact_interaction', 'interaction_id', 'contact_id')->withPivot('company_id')->withTimestamps();
}
Contact Model:
public function company()
{
return $this
->belongsToMany('App\Company', 'company_contact','contact_id', 'company_id')->withTimestamps();
}
and Company Model:
public function contacts()
{
return $this->belongsToMany('App\Contact', 'company_contact', 'company_id','contact_id');
}
Now I'm fetching some data something like this:
$tempData['contacts'] = $interaction->contactsAssociation()->with('company')->get();
I want to extract company data from the pivot table which is mentioned in the relationship. Currently I can't find solution so I have to do:
$tempData['contacts'] = $interaction->contactsAssociation()->get();
$companies = [];
foreach($tempData['contacts'] as $contact)
{
$companies[] = Company::find($contact->pivot->company_id);
}
$tempData['company'] = $companies;
Guide me on this, thanks,
You can pass an array to the withPivot() function with every field you want to retrieve:
public function contactsAssociation()
{
return $this->belongsToMany('App\Contact', 'contact_interaction', 'interaction_id', 'contact_id')
->withPivot(['company_id', 'other_field'])
->withTimestamps();
}
Hope this helps you.

Resources