laravel relation with 3 table using Eloquent? - laravel-5

i wanna use multiple hasMany and belongsTo that propositions uses two function, onece for return notes and another once for return actions
how can retrieve data note from Action::with('proposition ')
Model Proposition
public function proposition()
{
return $this-
>belongsTo('App\Proposition','proposition_num_proposition');
}
Model Action
public function action() {
return $this->hasMany('App\Action','proposition_num_proposition');
}
Model Note
public function notes(){
return $this->hasMany('App\Note','proposition_num_proposition');
}
And tables
proposition
num_proposition
proposition
Action
id_action
action
prposition_num_proposition
Note
id_note
note
proposition_num_proposition
in Controller
$actions = Action::all();
$propositions = Proposition::with('actions');
$notes = Note::all();
$propositions2 = Proposition::with('notes');
in view
i wanna retrieve data from proposition where(note.proposition_num_proposition = action.proposition_num_proposition)
using the laravel elequont
Any help plz ?

Have you tried to use it like this
$actions = Action::with(['proposition', notes])->get();
Or you can look at eager loading in the laravel docs
If you use array as input by with should solve your problem

Related

How to use custom model function in eloquent

I want to get all user's online friends, how can I call a custom model function inside the eloquent condition?
this is my code
$friends = $user->friends()->where(function (Builder $query){
$query->where('friend', 'yes');
})
->get();
and this is my function in model
public function getIsOnlineAttribute(): bool
{
// check if the user is online or not
return $this->is_online;
}
I can access is_online after eloquent by foreach, but in my case, I want to check everything in one step ( inside where condition in eloquent). how can I do that???
You can't use conditions for eloquent accessors, in this case you can use (assume 1 is database column value):
$friends = $user->friends()->where('is_online', 1)->get();
or
$friends = $user->friends()->whereIsOnline(1)->get();
or you can create eloquent scope on your model:
public function scopeIsOnline($query) {
$query->where('is_online',1);
}
and you can use this eloquent scope on your controller in this way:
$friends = $user->friends()->isOnline()->get();
this worked for me :)
$friends = $user->friends()
->simplePaginate()
->reject(function ($friend) {
return $friend->is_online === false;
});

How can I get a query with a conditional in a third relation?

Im using Laravel 7 and to get an array like this Array image spect result
And im working with Eloquent. This is my code for that array
**return EvaluateTeacherQuestion::with('evaluate_teacher_possibles_answers')->get();**
And this is my function evaluate_teacher_possibles_answers to make the relationship
public function evaluate_teacher_possibles_answers()
{
return $this->hasMany(EvaluateTeacherPossibilites::class)->withCount('evaluate_teacher_answers')->with('evaluate_teacher_answers');
}
And to get the third condition use this
public function evaluate_teacher_answers()
{
return $this->hasMany(EvaluateTeacherAnswer::class, 'evaluate_teacher_possible_id');
}
The problem is in the table evaluate_teacher_answers, I need get only this that if a condition (teacher_id = $teacher) is right.
When you add the whereHas condition a subquery is added.
Eg:
EvaluateTeacherQuestion::with('evaluate_teacher_possibles_answers')->whereHas('evaluate_teacher_possibles_answers',function($query){
$query->where('column','operation','value');
})->get();
With this way, will included relation in model and will execute conditions on closure from related model
Try this way:
remove with('evaluate_teacher_answers') from evaluate_teacher_possibles_answers relation:
public function evaluate_teacher_possibles_answers()
{
return $this->hasMany(EvaluateTeacherPossibilities::class)->withCount('evaluate_teacher_answers')->;
}
then load that relation with your condition:
$value = EvaluateTeacherQuestion::with(['evaluate_teacher_possibles_answers'=>function($query)use($teacher_id)
{
$query->with(['evaluate_teacher_answers'=>function($query)use($teacher_id){
$query = $query->where('evaluate_teacher_answers.teacher_id',$teacher_id);
}]);
}])->get();

How to retrieve multiple relations with multiple tables in laravel eloquent

I'm using Laravel 5.8 to build a babysitting site. I have 4 tables with different relationships as below:
please see this image
The relationships are:
Babysitter->hasMany(session)
Sessions->hasOne(Review)
Sessions->hasOne(Kids)
Sessions->hasOne(Babysitter)
Sessions->hasOne(Parent)
I want to achieve 2 things:
First one
I want to show this result when listing all babysitters. I'm showing this information for each babysitter:
plsease see this image
See here what I couldn't achieve
plsease see this image
This is my code
Sitters::where('Status', 'active')->where('Verified', 1)->get();
Second one
Also, I've tried to show kids name with parent review as shown here:
plsease see this image
This is what i'm using
Sessions::select('Reviews.*', 'Sessions.Parent_id')->join('Reviews', 'Reviews.Session_id', '=', 'Sessions.id')->with('owner')->where('Trainer_id', session('user')->Id)->where('Status', '=', 'complete')->with('owner')->orderBy('Sessions.id', 'DESC')->get();
Here is Session.php Model
public function owner(){
return $this->belongsTo('App\Models\Parents', 'Parent_id');
}
As discussed change the relations:
Babysitter->hasMany(sesstion)
Sessions->hasOne(Review)
Sessions->belongsTo(Kids)
Sessions->belongsTo(Babysitter)
Sessions->belongsTo(Parent)
First one
in Babysitter.php declare the following attributes
class Babysitter extends Model
{
public function reviews()
{
$this->hasManyThrough(Review::class, Session::class);
}
public function getAverageReviewAttribute()
{
return $this->reviews()->avg('Rating');
}
}
Then you just need to call it on the model instance.
$babysitter = Babysitter::first();
return $babysitter->average_review;
Second one
Just use the relation
$babysitter = BabySitter::with(['sessions' => public function ($session) {
$session->with(['review','parent','kids']);
})->where('trainer_id', '=', session('user')->Id) //did not understand this condition
->first();
This assumes you have parent, kids and review relation declared on Session::class. (change the names if needed)
After a few days of searching & testing, this is what worked for me:
Inside (Sitters) Model, put this relation
public function sessions()
{
return $this->hasMany(Sessions::class, 'sitter_id')
->withCount('reviews')
->withCount(['reviews as review_avg' => function($query){
$query->select(DB::raw('AVG(Rating)'));
}]);
}
Also, inside (Sessions) Model, put this relation
public function reviews()
{
return $this->hasOne(Reviews::class, 'Session_id');
}
Now you query like this
return $sitters = Sitters::with('sessions')->get();
I hope this can help someone :)

Laravel oneToMany accessor usage in eloquent and datatables

On my User model I have the following:
public function isOnline()
{
return $this->hasMany('App\Accounting', 'userid')->select('rtype')->latest('ts');
}
The accounting table has activity records and I'd like this to return the latest value for field 'rtype' for a userid when used.
In my controller I am doing the following:
$builder = App\User::query()
->select(...fields I want...)
->with('isOnline')
->ofType($realm);
return $datatables->eloquent($builder)
->addColumn('info', function ($user) {
return $user->isOnline;
}
})
However I don't get the value of 'rtype' for the users in the table and no errors.
It looks like you're not defining your relationship correctly. Your isOnline method creates a HasMany relation but runs the select method and then the latest method on it, which will end up returning a Builder object.
The correct approach is to only return the HasMany object from your method and it will be treated as a relation.
public function accounts()
{
return $this->hasMany('App\Accounting', 'userid');
}
Then if you want an isOnline helper method in your App\User class you can add one like this:
public function isOnline()
{
// This gives you a collection of \App\Accounting objects
$usersAccounts = $this->accounts;
// Do something with the user's accounts, e.g. grab the last "account"
$lastAccount = $usersAccounts->last();
if ($lastAccount) {
// If we found an account, return the rtype column
return $lastAccount->rtype;
}
// Return something else
return false;
}
Then in your controller you can eager load the relationship:
$users = User::with('accounts')->get(['field_one', 'field_two]);
Then you can do whatever you want with each App\User object, such as calling the isOnline method.
Edit
After some further digging, it seems to be the select on your relationship that is causing the problem. I did a similar thing in one of my own projects and found that no results were returned for my relation. Adding latest seemed to work alright though.
So you should remove the select part at very least in your relation definition. When you only want to retrieve certain fields when eager loading your relation you should be able to specify them when using with like this:
// Should bring back Accounting instances ONLY with rtype field present
User::with('accounts:rtype');
This is the case for Laravel 5.5 at least, I am not sure about previous versions. See here for more information, under the heading labelled Eager Loading Specific Columns
Thanks Jonathon
USER MODEL
public function accounting()
{
return $this->hasMany('App\Accounting', 'userid', 'userid');
}
public function isOnline()
{
$rtype = $this->accounting()
->latest('ts')
->limit(1)
->pluck('rtype')
->first();
if ($rtype == 'Alive') {
return true;
}
return false;
}
CONTROLLER
$builder = App\User::with('accounting:rtype')->ofType($filterRealm);
return $datatables->eloquent($builder)
->addColumn('info', function (App\User $user) {
/*
THIS HAS BEEN SUCCINCTLY TRIMMED TO BE AS RELEVANT AS POSSIBLE.
ARRAY IS USED AS OTHER VALUES ARE ADDED, JUST NOT SHOWN HERE
*/
$info[];
if ($user->isOnline()) {
$info[] = 'Online';
} else {
$info[] = 'Offline';
}
return implode(' ', $info);
})->make();

Laravel ORM should return Relation

Is it possible to return an value for an hasOne relation directly with an Model?
For example:
$List = Element::orderBy('title')->get();
The Element has a "hasOne" Relation to an column:
public function type()
{
return $this->hasOne('App\Type', 'id', 'type_id');
}
How can i now return automatically the "type" for the Model?
At the Moment i am looping through all Elements, and build my own "Array" of Objects, including the Key of "type" in this example. But ill prefer to do this only in my Model.
Ill know how to add a "normal" property, but can it be someone from an relation?
public function getTypeAttribute($value)
{
return // how ?
}
protected $appends = array('type');
Is this possible?
Edit:
A workaround could be to use DB:: to return the correct value - but ill dont thing thats a good workaround: like:
public function getTypeAttribute($value)
{
// make a query with $this->type_id and return the value of the type_name
}
protected $appends = array('type');
you need to eager load your relations when getting the Element:
$list = Element::with('type')->orderBy('title')->get();
then access the type using
foreach ($list as $item) {
echo $item->type->type_name;
}
where type_name would be the name of a column in the types table
Make a query scope and in that scope, join your attributes from other tables.
http://laravel.com/docs/5.1/eloquent#query-scopes
http://laravel.com/docs/5.1/queries#joins

Resources