Convert query from query builder t to Eloquent Query - laravel

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.

Related

nested query with laravel model

I am writing a nested query with Laravel.
Namely First, the Truck information is drawn, then I list the data of the vehicle with "truck_history", there is no problem until here, but I want to show the information of the invoice belonging to the "invoice_id" in truck_history. but I couldn't understand how to query, I want to do it in the model, is this possible? If possible, how will it be done?
"ID" COLUMN IN INVOICE TABLE AND "invoice_id" in "InvoiceDetail" match.
TruckController
public function getTruck($id)
{
$truck = Truck::with(['truckHistory'])->find($id);
return $truck;
}
Truck Model
protected $appends = ['company_name'];
public function companys()
{
return $this->belongsTo(Contact::class, 'company_id', 'id');
}
public function getCompanyNameAttribute()
{
return $this->companys()->first()->name;
}
public function truckHistory(){
return $this->hasMany(InvoiceDetail::class,'plate_no','plate');
}
So you can add another relationship in the InvoiceDetail::class and add in the truck history.
try something like this:
public function truckHistory(){
return $this->hasMany(InvoiceDetail::class,'plate_no','plate')->with('Invoice');
}
Simply add the following relations (if you don't already have them):
Invoice model :
public function truckHistory()
{
return $this->hasOne(InvoiceDetail::class);
}
InvoiceDetail model :
public function invoice()
{
return $this->belongsTo(Invoice::class);
}
And you can get the relation invoice of the relation truckHistory adding a point as separator :
public function getTruck($id)
{
$truck = Truck::with(['truckHistory.invoice'])->find($id);
return $truck;
}

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 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.

How to filter a polymorphic relationship to only return a specific model?

I'm having an issue with defining a function to filter a polymorphic relationship and only return a specific model. I'll try to explain below:
Say I have three models: A, B, and C. Model A can belong to either of the other two models. Say we're using the polymorphism field name of recipient, so on our model A database schema we have recipient_type and recipient_id.
On model A, I have a the default function called recipient, defined like so:
public function recipient()
{
return $this->morphTo();
}
However, I want a function called b() which will return a relationship so that it can be used with a query builder using the with() function. The idea being I can call $a->b and it will either return an instance of B or null, depending on whether the instance of A belongs to and instance of B...
Sorry this has been a bit of a mouthful..
Appreciate all the help I can get with this one!
Cheers!
You can define it like this
Model A (define accessor)
public function recipient()
{
return $this->morphTo();
}
public function bRelation()
{
return $this->belongsTo(B::class, 'recipient_id', 'id');
}
public function cRelation()
{
return $this->belongsTo(C::class, 'recipient_id', 'id');
}
public function getBAttribute(){ //define accessor
if($this->recipient_type == 'App\B') return $this->bRelation;
return null;
}
public function getCAttribute(){ //define accessor
if($this->recipient_type == 'App\C') return $this->cRelation;
return null;
}
Now use it with eager loading
$records = A::with('bRelation', 'cRelation')->get();
foreach($records as $a){
dd($a->b); //it will return you either instance of `B` or `null`
}
Works well with accessors:
public function getIssueAttribute()
{
if($this->commentable_type == 'issues') return $this->commentable;
return null;
}
public function getProjectAttribute()
{
if($this->commentable_type == 'projects') return $this->commentable;
return null;
}
public function commentable()
{
return $this->morphTo('commentable');
}

laravel- eloquent relationships

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 :)

Resources