I have a user who speaks native language lets say English and wants to learn French.
How can I find a list of match where users native is French and wants to learn English.
Its a language exchange program so I would like to list users with the match.
I have Users, Language_User and Language table. in Language_User table I have an extra field called type(learn or native).
Users
id
name
...
Language_User
id
user_id
language_id
type('learn','native')
Language
id
language
Queries
First I am getting all the users that does not have a role as 'Admin' or is not him/herself.
$other_users = User::with('languages')->with('departments')->with('hobbies')->with('universities')->with('years')->where([['id', '<>', Auth::user()->id],['role', '<>', 2]])->get();
Then, I am getting loggedin users $learn language and $native language to compare with other users
$learn = Auth::user()->languages()->wherePivot('type', 'learn')->select('language_id')->first();
$native = Auth::user()->languages()->wherePivot('type', 'native')->select('language_id')->first();
In View
gives loggedin user language to learn
{{$learn->language_id}}
gives loggedin user native language
{{$native->language_id}}
View Code
#foreach($other_users as $user)
#foreach($user->languages as $lang)
#if($lang['pivot']['type'] ==='native' AND $lang['pivot']['language_id'] ===$learn['language_id'])
<tr>
<td>{{$user->firstname}} </td>
<td>{{$user->lastname}} </td>
<td>{{$user->email}} </td>
<td>{{$user->photo}} </td>
<td>{{$user->bio}} </td>
<td>{{$user['universities']->university}} </td>
<td>{{$user['departments']->department}} </td>
<td>{{$user['years']->year}} </td>
<td>
#foreach($user->languages as $lang)
#if($lang['pivot']['type'] === 'native')
{{$lang["language"]}}
#endif
#endforeach
</td>
<td>
#foreach($user->languages as $lang)
#if($lang['pivot']['type'] === 'learn')
{{$lang["language"]}}
#endif
#endforeach
</td>
<td>
#foreach($user->hobbies as $hobby)
{{$hobby->hobby}} <br>
#endforeach
</td>
</tr>
#endif
#endforeach
#endforeach
I am unable to put two if conditions one for checking native language and one for checking learn language. if I do like this:
#if($lang['pivot']['type'] ==='native' AND $lang['pivot']['language_id'] ===$learn['language_id'])
#if($lang['pivot']['type'] ==='learn' AND $lang['pivot']['language_id'] ===$native['language_id'])
I get no rows, whereas user do exist with a match.
I think because I have two pivot type learn and native in an array. how to compare both learn and native? below shown languages format. its many to many relation
"languages":[
{
"id":3,
"language":"Spanish",
"pivot":{
"user_id":2,
"language_id":3,
"type":"native"
}
},
{
"id":4,
"language":"Greek",
"pivot":{
"user_id":2,
"language_id":4,
"type":"learn"
}
}
]
Instead of loop through all the users in the database you could just constrain your query:
$native = Auth::user()->languages()->wherePivot('type', 'native')->first();
$learn = Auth::user()->languages()->wherePivot('type', 'learn')->first();
$other_users = User::with('departments', 'hobbies', 'universities', 'years', 'languages')
->where('id', '<>', Auth::user()->id)
->where('role', '<>', 2)
->whereHas('languages', function ($query) use ($learn) {
$query->where('type', 'native')->where('id', $learn->id);
})
->whereHas('languages', function ($query) use ($native) {
$query->where('type', 'learn')->where('id', $native->id);
})
->get();
Also, just an FYI, $lang['pivot']['type'] can also be written as:
$lang->pivot->type;
Your blade section could then look something like:
#foreach($other_users as $user)
<tr>
<td>{{ $user->firstname }} </td>
<td>{{ $user->lastname }} </td>
<td>{{ $user->email }} </td>
<td>{{ $user->photo }} </td>
<td>{{ $user->bio }} </td>
<td>{{ $user->universities->university }} </td>
<td>{{ $user->departments->department }} </td>
<td>{{ $user->years->year }} </td>
<td>
{{ $user->languages->where('pivot.type', 'learn')->first()->language }}
</td>
<td>
{{ $user->languages->where('pivot.type', 'native')->first()->language }}
</td>
<td>
{!! $user->hobbies->pluck('hobby')->implode('<br>') !!}
</td>
</tr>
#endforeach
Hope this helps!
Related
I am working in Laravel 7, pulling data from my db and showing the student his/her score on the scores page in percentage via the following codes.
In my StudentOperationController.php
public function show_result($id) {
$data['result_info'] = Oex_result::where('id', $id)->get()->first();
$data['student_info'] = Oex_students::select(['oex_students.*', 'oex_exam_masters.title', 'oex_exam_masters.exam_date'])->join('oex_exam_masters', 'oex_students.exam', '=', 'oex_exam_masters.id')->where('oex_students.id', Session::get('id'))->get()->first();
return view('student.show_result', $data);
}
and in my show_result.blade.php
<h2>Result Information</h2>
<table class="table">
<tr>
<td>Number Correct</td>
<td>{{ $result_info->yes_ans }}</td>
</tr>
<tr>
<td>Number Incorrect</td>
<td>{{ $result_info->no_ans }}</td>
</tr>
<tr>
<td>Total</td>
<td>{{ round($result_info->yes_ans / ($result_info->yes_ans + $result_info->no_ans) * 100 , 1) }} %</td>
</tr>
</table>
The reason I show this is that it works as expected. this is within the students dashboard. In my admin, I am trying to do the same thing and show that students data for his/her exam result. In my database, I have a json type data for example: {"2":"YES","3":"YES","8":"YES"}. I am still learning Laravel and am stuck on how to get this data to my admin. I am clearly doing something wrong and am in need of assistance. Here is what I have tried:
AdminController.php
public function manage_students($id)
{
$data['result_info'] = Oex_result::where('id', $id)->get()->first();
// dd($data);
$data['student_info'] = Oex_students::select(['oex_students.*', 'oex_exam_masters.title', 'oex_exam_masters.exam_date'])->join('oex_exam_masters', 'oex_students.exam', '=', 'oex_exam_masters.id')->where('oex_students.id', Session::get('id'))->get()->first();
$data['exams'] = Oex_exam_master::where('status', '1')->get()->toArray();
$data['students'] = Oex_students::select(['oex_students.*', 'oex_exam_masters.title as exam_name'])
->join('oex_exam_masters', 'oex_students.exam', '=', 'oex_exam_masters.id')
->get()->toArray();
return view('admin.manage_students', $data);
}
and in my manage_students.blade.php, I have
<tbody>
#foreach($students as $key => $student)
<tr>
<td>{{ $key+1 }}</td>
<td>{{ $student['name'] }}</td>
<td>{{ $student['email'] }}</td>
<td>{{ $student['mobile_no'] }}</td>
<td>{{ $student['exam_name'] }}</td>
{{-- <td>N/A</td> --}}
<td>{{ round($result_info->yes_ans / ($result_info->yes_ans + $result_info->no_ans) * 100 , 1) }} % </td>
#if($student['status']== 1)
<td><input data-id="{{ $student['id'] }}" class="student_status" type="checkbox" name="status" checked></td>
#else
<td><input data-id="{{ $student['id'] }}" class="student_status" type="checkbox" name="status"></td>
#endif
<td>
Edit
Delete
</td>
</tr>
#endforeach
</tbody>
In doing this I get the error Too Few arguments to function ... 0 passed and exactly 1 expected
I am unable to replicate what I have for the student dashboard and because of my lack of Laravel knowledge, I am having trouble solving this issue. So, any help would be greatly appreciated. If I am missing anything, please let me know so I can edit my question. Thanks in advance.
Edit: manage_students route:
Route::get('admin/manage_students', 'AdminController#manage_students');
Edit Number 2:
Too few arguments to function App\Http\Controllers\AdminController::manage_students(), 0 passed and exactly 1 expected
C:\laragon\www\lionsfieldtest\app\Http\Controllers\AdminController.php:146
Referring to this line:
public function manage_students($id)
Edit Number 3:
in resources/views/layouts/app.blade.php
<li class="nav-item">
<a href="{{ url('admin/manage_students') }}" class="nav-link">
<i class="nav-icon fas fa-school"></i>
<p>
Student Management
</p>
</a>
</li>
Edit number 4:
The manage_student page brings in data from a number of student's exam results
This function request $id;
public function manage_students($id)
This route doesn't pass one
Route::get('admin/manage_students', 'AdminController#manage_students');
As I can see you are filtering by results which in this case you need $result id
Route::get('admin/manage_student/{id}', 'AdminController#manage_students');
So you have to pass result ID, but lets assume there is a default results id
public function manage_students($id=2)
then this route works because $id is optional/predefined.
Route::get('admin/manage_students', 'AdminController#manage_students');
And if you pass an ID it will use
Route::get('admin/manage_student/{id}', 'AdminController#manage_students');
Make 2 routes and make parameter optional/predefined.
if you go to /admin/manage_student it will use ID 2
but if you pass /admin/manage_student/5 it will use 5
I have two tables in my program. The first one is tbfininst and the other is tbsubmission.
The tbfininst have a primary key of fld_code while the tbsubmission have a foreign key of CODCODE. It's a one to many relationship.
Now, I am displaying the rows of tbfininst in my blade.php. It looks like this.
Then, in the Submission (Periodicity) column, I want to insert how many rows from tbsumission does tbfininst have. By the way, the database is already created before I started. So I don't think I can use models or can i?
Anyways, in my controller, I tried using this code:
public function index()
{
$fininst = DB::connection('portaldb')->table('tbfininst')->groupBy('fld_code')->get();
$periodicity = DB::connection('portaldb')->table('tbsubmission')->select('CODCODE')->get();
return view('pages/compliance', ['fininst' => $fininst, 'periodicity' => $periodicity]);
}
and in my blade.php:
#foreach($fininst as $fin)
<tr>
<td>
<center>
{{ $fin->fld_code }}
</center>
</td>
<td>{{ $fin->fld_name }}</td>
<td>
#if ($fin->fld_status == 4)
<p>Compliant</p>
#else
<p>Non-Compliant</p>
#endif
</td>
<td>
#if ($fin->fld_ip || $fin->fld_twofactor)
<p>Compliant</p>
#else
<p>Non-Compliant</p>
#endif
</td>
<td>
#foreach($periodicity as $p)
#if ($fin->fld_code == $p->CODCODE)
{{$fin->fld_code}}
#else
#endif
#endforeach
</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
#endforeach
When I inserted the #foreach of the periodicity, my blade.php output kinda not works.
I don't know why my template is not working. I just started using laravel two days ago and I'm still learning. I accept criticism, it will help me improved. Thank you.
You are just showing the matching values where you should be counting the matching values and showing them like this
#foreach($fininst as $fin)
#php $count = 0; #endphp
#foreach($periodicity as $p)
#if ($fin->fld_code == $p->CODCODE)
#php ++$count; #endphp
#else
#endif
#endforeach
<tr>
<td>
<center>
{{ $fin->fld_code }}
</center>
</td>
<td>{{ $fin->fld_name }}</td>
<td>
#if ($fin->fld_status == 4)
<p>Compliant</p>
#else
<p>Non-Compliant</p>
#endif
</td>
<td>
#if ($fin->fld_ip || $fin->fld_twofactor)
<p>Compliant</p>
#else
<p>Non-Compliant</p>
#endif
</td>
<td>
{{$count}}
</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
#endforeach
I am trying to show the table like below image
And i write the logic for this table creation is below
#foreach($users as $key => $user)
<tr>
<td>{{$key+1}}</td>
<td>{{$user->name}}</td>
<td rowspan="{{count($users->where('area',$user->area))}}">
{{$user->userarea->name}}</td>
<td rowspan="{{count($user->candidate->election->candidates)}}">{{$user->candidate->election->name}}</td>
</tr>
#endforeach
</tbody>
But this code produce me the following code like this
Here The Election and Candidate has one to many relationships and candidate and user has one one to one relationshipHelp me achieve my expected results.
You could keep track of which elections/area's have been rendered already. This could be done by creating an array containing a reference to these objects. Then in the template just add an if statement checking whether an election/area has been rendered:
<?php $renderedElections = []; ?>
<?php $renderedAreas = []; ?>
#foreach($users as $key => $user)
<tr>
<td>{{$key+1}}</td>
<td>{{$user->name}}</td>
#if (!in_array($user->userarea->name, $renderedAreas))
<?php $renderedElections[] = $user->userarea->name ?>
<td rowspan="{{count($user->userarea->name)}}">
{{$user->userarea->name}}
</td>
#endif
#if (!in_array($user->candidate->election->name, $renderedElections))
<?php $renderedElections[] = $user->candidate->election->name ?>
<td rowspan="{{count($user->candidate->election->candidates)}}">
{{$user->candidate->election->name}}
</td>
#endif
</tr>
This is not the best solution, but its simple and easy. For this to work, the users must be sorted perfectly by election and area.
This code is untested but should theorethically work. I tryied to gather informations about your model relationships from the code you posted, but it might need some tweaking with the model names and relations.
The following code basically fetches all the users each with their area, candidate and candidate.election relationships, then group users by 'election name' (first criteria), then 'area name' (second criteria).
The resulting array will be something like this:
// $elections will be:
// [
// 'Presidential' => [
// 'Dhaka-5' => [ candidates for that area in that election type ],
// 'Dhaka-1' => [ candidates for that area in that election type ],
// ...
// ],
// ...
// ]
In your controller do:
$elections = User::with('area', 'candidate.election')->get()->groupBy(function ($user) {
return $user->candidate->election->name;
}, function ($user) {
return $user->area->name;
});
// then pass $elections to the view...
Then in your view:
<table>
#php ($i = 1)
#foreach ($elections as $election => $areas)
#foreach ($areas as $area => $candidates)
#php ($areaLoop = $loop)
#foreach ($candidates as $user)
<tr>
<td>{{ $i++ }}</td>
<td>{{ $user->name }}</td>
#if ($loop->first)
<td rowspan="{{ $candidates->count() }}">{{ $area }}</td>
#endif
#if ($areaLoop->first)
<td rowspan="{{ $areas->sum(function ($area) { return $area->count(); }); }}">{{ $election }}</td>
#endif
</tr>
#endforeach
#endforeach
#endforeach
</table>
Note that $candidates->count() will be the number of candidates for that particular election area of the current election type. $areas->sum(...) will sum the number of candidates for each area to get the total count of candidates in that election type.
If you need further explaination or something doesn't work, just let me know. All the documentation about the collection functions I used is available here.
I have 2 tables in my database - Bots and Results. The bots table is to have information on each specific bot alone. Each bot should have several results attached to it. I will simplify what I have in my columns:
Bots Table
Device | Info1 | Info2 | Info3
Results Table
Device | Data1 | Data2 | Data3
As you can see, each table has the column named Device. Now, I have 2 Models of course for each table - the regarding info is as follows:
Bot Model
public function results()
{
return $this->hasMany('App\Result', 'device', 'device');
}
Result Model
public function bots()
{
return $this->belongsTo('App\Bot', 'device', 'device');
}
I have a view with a Datatable in it which I am trying to list every Device and Every Result corresponding to that Device. What I have here is an example of what was made before eloquent relations was brought in. I use to only have the Results table, so therefore it was farely simple to do a foreach and loop throught every result I had to display on the Datatabes
Datatables View
#foreach ($results as $result)
<tr>
<td>
{{ $result->device }}
</td>
<td>
{{ $result->info1 }}
</td>
<td>
{{ $result->info2 }}
</td>
<td>
{{ $result->info3 }}
</td>
<td>
{{ $result->data1 }}
</td>
<td>
{{ $result->data2 }}
</td>
<td>
{{ $result->data3 }}
</td>
</tr>
#endforeach
How can I get this to work now that the device name and information is actually stored in a separate table?
You can fetch your device information with its associated results using eager load like this
$bots = Bot::with('results')->get();
Now in view you can do it like this
#foreach ($bots as $bot)
<tr>
<td>
{{ $bot->device }}
</td>
<td>
{{ $bot->info1 }}
</td>
<td>
{{ $bot->info2 }}
</td>
<td>
{{ $bot->info3 }}
</td>
</tr>
#foreach ($bot->results as $result)
<tr>
<td>
{{ $result->data1 }}
</td>
<td>
{{ $result->data2 }}
</td>
<td colspan="2">
{{ $result->data3 }}
</td>
</tr>
#endforeach
#endforeach
I had Users table and group table, when i load a group table, it loads the user which have same group_id as the group table id. it works, but my problem is the foreach was quite a mess. the output looks like this..
however, i want to make the output look like this.
here is my code..
<tbody>
<?php $i = 0; ?>
#foreach ($auser as $res)
<?php $i += 1; ?>
<tr #if($i%2==0) class="bgcolor" #endif>
<td>{{ $res->id }}.</td>
<td id="showdet">{{ $res->nama }}</td>
<td>{{ $res->description }}</td>
<?php $user = DB::table('users')->where('devgroup',$res->id)->get();?>
#foreach($user as $mem)
<td>{{ $mem->name }}</td>
#endforeach
<td>
<a class="default-btn" href="/pms/admin/group/edit/{{ $res->id }}">Edit</a>
<a type="submit" class="default-btn del" data-id="devgroup" href="#"{{ $res->id }}">Delete</a>
</td>
</tr>
#endforeach
</tbody>
what did i do wrong? thank you for your help.
You create new TD for each member. The nested foreach has to be:
<td>
#foreach($user as $mem)
{{ $mem->name }}<br>
#endforeach
</td>
The result will be:
<td>
Name 1<br>
Name 2<br>
Name 3<br>
</td>
I don't know the template engine you used, add inside a loop condition and don't put <br> after the last one member.