I'm using the following query to get all companies for a certain event. And they are ordered by name
$companies = Company::where('city_id', 3)->orderBy('name', 'asc')->get();
Now in my view i use eager loading to get all the persons that work for that company
#foreach($companies as $company)
#foreach($company->persons as $person)
<tr><td>{{ $person->firstname }}</td></tr>
#endforeach
#endforeach
I'm trying to sort the persons by name but it's not working. Any idea on how to do this?
Thanks
You can further query your relations in Laravel.
For example to get person by names in an ascending order.
#foreach($companies as $company)
#foreach($company->persons()->orderBy('firstname','asc')->get() as $person)
<tr><td>{{ $person->firstname }}</td></tr>
#endforeach
#endforeach
Related
Here a want to add Appointments available for the coach by using two tables...one for date_days the second for trainer and I make a 1-m relation between two tables.
Dateday Table...
class Dateday extends Model
{
public function trainer()
{
return $this->belongsTo(Trainer::class, 'trainer_id', 'id');
}
}
Trainer Table...
class Trainer extends Model
{
public function datedays()
{
return $this->hasMany(Dateday::class);
}
}
Trainer index ...
Show this way you give me an error, And I want To add a day and date and start_date/end_date to the index page for trainer Who can do this??
#foreach ($trainers as $trainer)
<tr>
<td>{{ $trainer->id }}</td>
<td>{{ $trainer->firstname }}</a></td>
<td>{{ $trainer->lastname }}</a></td>
<td>{{ $trainer->phone }}</a></td>
<-- Show this way you give me ero -->
<td>{{ $trainer->dateday->day}}</a></td>
<td>{{ $trainer->dateday->date}}</a></td>
</tr>
#endforeach
In your Trainer class, you have defined a function datedays, but in your template you are using $trainer->dateday without the s.
Regarding your edit
$trainer->datedays is a Collection of all the datedays associated with the trainer (because of the ->hasMany), so you cannot get the property of an individual item. If there should only be one date, the relation should be changed (->hasOne), or if there should be more dates possible, you should think about how you want to show that. If you (for example) only want to show the first date you could use {{ $trainer->datedays->first()->day }} or you could loop over all dates using #foreach ($trainer->datedays as $dateday) and use {{ $dateday->day }} in the loop.
i’m looking for a solution to a problem that I’m having for a while now. Maybe you can inspire me to do this better. I’m trying not to make a basic mistake in the planning process therefore I’m asking you for advice.
I’m having a Contact::model which has few fixed attributes like id etc. Additionally I would like to have different attributes created dynamically for the whole Contact::model. Some user will be given the functionality to add attributes like name, email, address to the whole model. I’ve dropped the idea of programmatically updating the table itself by creating/dropping columns (this would introduce different problems). As for now i've created two additional tables. One with the additional column names [Columns::model] and a pivot table to assign the value to a Contact::model and Column::model.
To list all contacts i’m preparing the ContactColumn table as array where the first key is the contact_id and the second is the column_id, therefore i get the value. This introduces the n+1 issue. This would not be that bad, but with this approach it will be extremely hard (or resource consuming) to order the contacts by dynamic column values, filtering, searching etc.
Can you somehow guide me to a better solution. How can i merge the contact collection with the values for given columns so it looks like it was a fixed table?
<table>
<thead>
<tr>
<th>Fixed columns [i.e. ID]</th>
#foreach ($columns as $column)
<th>{{ $column->name }}</th>
#endforeach
</tr>
</thead>
<tbody>
#foreach ($contacts as $contact)
<tr>
<td>{{ $contact->id }}</td>
#foreach ($columns as $column)
<td>
#if (array_key_exists($column->id, $values[$contact->id]))
{{ $values[$contact->id][$column->id] }}
#endif
</td>
#endforeach
</tr>
#endforeach
</tbody>
</table>
And the $value array.
foreach (ColumnContact::all() as $pivot) {
$values[$pivot->contact_id][$pivot->column_id] = $pivot->value;
}
return $values;
Edit: I've solved it like this
$this->contacts = Contact::when($this->dynamicColumnName, function($query) {
$query->join('column_contact', function ($join) {
$join->on('id', '=', 'column_contact.contact_id')
->where('column_contact.column_id', '=', $this->dynamicColumnName->id);
})
->orderBy('value', $this->orderingDirection);
})
(...)
->paginate(self::PER_PAGE);
Apart from the fixed fields, add an extra JSON field in your schema called 'custom_fields'. Have a look into => https://github.com/stancl/virtualcolumn
Separate table for custom fields is not a good idea because then you have to handle model events separately and so on.
I want to explode array value and have successfully doing so by using this code :
#foreach(explode('.', $comment->topic_id) as $topic)
{{ $topic }}
#endforeach
This is the output
Topic : 1,2
The problem is, I want to implement relation belongsTo to the topic_id. When I add the relation and run the code, unfortunately only one of the value is shown.
#foreach(explode('.', $comment->getTopic->topic) as $topic)
{{ $topic }}
#endforeach
This is my model
public function getTopic()
{
return $this->belongsTo('App\Topic', 'topic_id', 'id');
}
Output :
Topic : Laravel
What is the right way to call this array? Please help me. Thank you.
You can't use relationship in this case. If you simply looking for solution then you could do something like the following:
<?php $topic_ids = explode('.', $comment->topic_id);
$topics = App\Topic::whereIn(id, $topic_ids)->get();
?>
#foreach($topics as $topic)
{{ $topic }}
#endforeach
BTW you should structure your database more efficiently.
#foreach(explode(',', $item->chapter_id) as $layer)
<?php
$chapters = DB::table('topic_types')->where('id', $layer)->get();
?>
#foreach ($chapters as $ch)
{{$ch->name}} <br>
#endforeach
#endforeach
Let's say I have 250 users in users table and each user has one or many books, and each book has one or many chapters. Now I would like to print the user names, with their book names.
Controller:
$users = User::all();
in blade:
#foreach($users as $user)
<tr>
<td>{{ $user->id }}</td>
<td>{{ $user->name }}</td>
<td>
#foreach($user->books as $book)
{{ $book->name }},
#endforeach
</td>
</tr>
#endforeach
# of queries 252
Now to overcome the n+1 problem, the query should be
$users = User::with('books')->get();
Now the # of queries are only 2.
I want to print the book names with number of chapters like this->
BookName(# of chapters). So in my blade
#foreach($users as $user)
<tr>
<td>{{ $user->id }}</td>
<td>{{ $user->name }}</td>
<td>
#foreach($user->books as $book)
{{ $book->name }} ({{ $book->chapters->count() }}),
#endforeach
</td>
</tr>
#endforeach
so for 750 books with 1500 chapters the # of queries are about 752 and it increases if chapter number increases.
Is there any better Eloquent way to reduce it or should I go for raw SQL queries?
You don't need to load all chapters data and then manually count each collection. Use withCount() instead:
$users = User::with('books')->withCount('chapters')->get();
If you want to count the number of results from a relationship without actually loading them you may use the withCount method, which will place a {relation}_count column on your resulting models.
From the Eloquent Documentation:
Nested Eager Loading
To eager load nested relationships, you may use "dot" syntax. For example, let's eager load all of the book's authors and all of the author's personal contacts in one Eloquent statement:
$books = App\Book::with('author.contacts')->get();
In your case, you can retrieve the nested relationships you need with the following:
User::with('books.chapters')->get();
I have two database table
1. patient
--id
--name
2. report
--id
--description
and pivot talbe
patient_report
--id
--report_id
--patient_id
My Patient Model
class Patient extends Model
{
public function reports()
{
return $this->belongsToMany('App\Report' , 'patient_reports');
}
}
My Report Model
class Report extends Model
{
public function patients()
{
return $this->belongsToMany('App\Patient' , 'patient_reports');
}
}
My ReportControlller
public function viewList($reportFloor = null)
{
$report = Report::orderBy('created_at' , 'desc')->paginate(50);
return view('admin.report_list' , ['reports' => $report]);
}
Database : patients table have report_id column and reports table have patient_id column
N.B : I want to find the patient name who has a report. And i am using the laravel dynamic properties like that ---
And finally my blade
#foreach ($reports as $report)
{{ $report->patients->name }}
#endforeach
But it provides an error like that
Try this:
#foreach ($reports->patients as $patient)
{{ $patient->name }}
#endforeach
As the error implies, you're attempting to access the name attribute on a collection. To fix you should change:
#foreach ($reports as $report)
{{ $report->patients->name }}
#endforeach
to:
#foreach ($reports as $report)
#foreach ($report->patients as $patient)
{{ $patient->name }}
#endforeach
#endforeach
In your controller, i would first find the patients and afterwards get their reports.
$patients = Patient::with('reports')->get();
And then in the view i would do:
//This will first get all the patients
#foreach ($patients as $patient)
// This will get each of patients relational reports
#foreach ($patient->reports as $report)
{{ $report->name }}
#endforeach
#endforeach