How do I show a table's Has Many relationship on frontend? - laravel

Using Laravel + Voyager, I have a "Has Many" relationship:
Course hasMany Teachers.
In backend all is fine, but if I try to get the information in the frontend, I only get the value in table, not the relation, so the output goes something like:
0
id 1
teachers_id null
name "Math"
1
id 2
teachers_id null
name "English"
Current code in web routing:
Route::get('/course', function () {
$co= App\Course::all();
return $co;
});
How can I get the correct output?
teachers_id Xav, Titus

so like #Tpojka commented you can start by eager loading the relationship when you are initializing the course likeso $co = App\Course::with('teachers')->get(); after which you do not need to make another unnecessary call to your database for the teachers of that course. You can get a collection of all the teachers of that course by simply calling $teachers = $co->teachers; here $teachers is now a laravel collection you can simply loop through it on the client side and display the information about the teachers you want to display. I hope this helps.
Good luck and happy coding. :)

Related

Can't get ID from created Eloquent model extending Pivot in Laravel

Maybe simple, but I can't figure it out...
When I create a record using Eloquent and a model that extends Model, and then get its id right after it just works:
$example = Example::create(['name'=> 'exie']);
dd($example->id);
// returns id (ex. 15) as expected from the created record...
When I create a record using a model that extends Pivot and try to get id, it only returns null.
$customPivotExample = CustomPivot::create(['name' => 'custie']);
dd($customPivotExample->id);
// returns null instead of id...
The records all have a PK so I expected to just get the ID back, but apparently there is something about using a custom pivot model and getting it's id after creation what I am overlooking..
(examples are really simple but the actual code only contains more key=>value pairs and nothing more)
anyone has any idea?
Own Answer
Putting this here because this is not written (somewhat) in the Laravel documentation.
They mention this about auto incrementing ID's:
https://laravel.com/docs/9.x/eloquent-relationships#custom-pivot-models-and-incrementing-ids
I had not done this (my bad), but doing this also enables getting the ID after creation of a pivot record as in my second example....

Using Laravel Eloquent to count how many times something exists in an efficient manner

I have a table called rentals, within each row are columns state,city,zipcode which all house ids to another table with that info. There are about 3400 rentals. I am pulling each column to display the states,city and zipcode distinctly. I need to show how many rentals are in each one. I am doing this now via ajax, the person starts typing in what they want to see and it auto completes it with the count, but its slow because of the way im doing it.
$rentals_count = Rentals::where('published',1)->get();
foreach($states as $state) {
echo $state.”-“.$rentals_count->where(‘state’,$state->id)->count();
}
Above is roughly what im doing with pieces removed because they are not related to this question. Is there a better way to do this? It lags a bit so the auto complete seems broken to a new user.
Have you considered Eager loading your eloquent query? Eager loading is used to reduce query operations. When querying, you may specify which relationships should be eager loaded using the with method:
$rental_counts = Rentals::where('published',1)->with('your_relation')->get();
You can read more about that in Laravel Documentation
$rentals = Rentals::wherePublished(true)->withCount('state')->get();
When you loop through $rentals, the result will be in $rental->state_count
Setup a relation 'state' on rentals then call it like this
$rentals_count = Rentals::where('published',1)->with('state')->get()->groupBy('state');
$rentals_count->map(function($v, $k){
echo $v[0]->state->name .' - '. $v->count();
});
Meanwhile in Rentals Model
public function state(){
return $this->hasOne(State::class, 'state'); //state being your foreign key on rentals table. The primary key has to be id on your states table
}

Laravel Validation Rule

I have category table
Its has del_status
when delete category delstatus will change 1
now question is
when update category ,
I want to validate except del_status 0
because category is unique
eg below is pseudo code :)
Rule::except(function ($query){
return $query->where('del_status','1');
})
You should use The softDelete traits in your model. it will spare you a lot of trouble and will work as you want it to.
https://laravel.com/docs/5.7/eloquent#soft-deleting
it will use a field in the DB table name deleted_at

Updating a pivot table in Eloquent

I've got a many to many relationship between a student and an institution_contact.
students should only ever have two institution_contacts and I have an attribute on the pivot table named type to be set as 1 or 2.
So, my pivot table looks like this:
institution_contact_student: id, institution_contact_id, student_id, type
I've run into difficulty in deciding how to approach the issue of adding/updating the pivot table. Let's say I have 100 students and I want to assign them a contact with the type of 1.
My current solution is to delete the contact then add it:
$students = Student::all(); // the 100 students
$contactId = InstitutionContact::first()->id; // the contact
foreach ($students as $student) {
// remove existing contact
$student
->institutionContacts()
->newPivotStatement()
->where('type', 1)
->delete();
// add new contact
$student
->institutionContacts()
->attach([$contactId => ['type' => 1]]);
}
However, I'm thinking that this is going to hit the database twice for each student, right? So would I be better off creating a model for the pivot table and removing all entries that matched the student id and the type then simply adding the new ones? Or would creating a model for the pivot table be considered bad practice and is there a better way of accomplishing this that I've missed?
Please note the reason I'm not using sync is because I'm relying on the type attribute to maintain only two contacts per student. I'm not aware of a way to modify an existing pivot without causing issues to my two contacts per student requirement.
Edit:
Instead of creating a model I could run the following code to perform the delete using DB.
DB::table('institution_contact_student') // the pivot table
->whereIn('student_id', $studentIds)
->where('type', 1)
->delete();
If I have understood your question correctly then you can use the updateExistingPivot method for updating your pivot table.But first of course you have to define the pivot in your relationship. For instance,
public function institutionContacts(){
return $this->belongsToMany('institutionContact')->withPivot('type');
}
after this, all you have to do is use the following code:
$student
->institutionContacts()
->updateExistingPivot($contactId, ["type" => 1]);
Hope this helps.

return separate result for each relation in many to many

Hi i have a many to many relationship with the following structure:
services
apps
service_app
I would like to have an eloquent query to return a separate result for each relationship(basically the pivot table). I have the following :
$all = App::with('services')->get();
this will return an app with nested services, I would like to have this return a separate result for each app-service combination along with data from the pivot table. how is this possible using eloquent?
It's a bit strange, but it can easily be done if you don't think of the pivot table as a pivot table, but as an AppService.
So what you can do is create a model for it, probably named AppService. In that model, you would then have 2 belongsTo() relationships. One for App and one for Service.
Then you can query your pivot table directly and use those relationships to get what you need.
$appServices = AppService::all();
foreach($appServices as $appService) {
echo $appService->app->description;
echo $appService->service->description;
}

Resources