I have 3 tables
auctions [id, winner_user_id, title]
bids [id, auction_id, amount, user_id]
users [id, name]
relations
Auction
...
public function winningBidder(){
return $this->belongsTo('User', 'winner_user_id', 'id');
}
public function bids(){
return $this->hasMany('Bid');
}
User
...
public function bids(){
return $this->hasMany('Bid');
}
Bid
...
public function auction(){
return $this->belongsTo('Auction');
}
public function user(){
return $this->belongsTo('User');
}
What i am trying to do is the highest bid for the winner
eager load
$auctions = Auction::with('winningBidder.bids')->get();
loads all bids instead of bids of that auction and adding max(amount) to about will give max of all
is it possible to get highest bid of winning user for each auction?
If you want to eager load the winningBidders and the winningBid with each auction you could do the following:
In your Auction model add a new one-to-one relationship for the highest / winning bid:
public function winningBid()
{
return $this->hasOne('Bid')->max('amount');
}
Then you can do the following:
$auctions = Auction::with(['winningBidder', 'winningBid'])->get();
Related
I want to recieve all users from a group.
The problem is in this group their are student users (with a pivot table) and normal users.
So i have to merge them together, but i still want to maintain all possibilities from eloquent.
I came to this:
dd($this->belongsToMany(User::class)->union($this->hasManyThrough(User::class,Student::class,'class_id','id','id','user_id'))->get());
But as result i get:
My database relationships
Users
- id
Group
- id
Students
- id
- user_id (fk to users)
- class_id (fk to groups)
User_Group
- user_id (fk to users)
- group_id (fk to groups)
User-model:
public function students()
{
return $this->hasMany(Student::class);
}
public function groups()
{
return $this->belongsToMany(Group::class);
}
Student-model
public function user()
{
return $this->belongsTo(User::class, 'user_id');
}
public function class()
{
return $this->belongsTo(Group::class, 'class_id');
}
Group-model
public function students()
{
return $this->hasMany(Student::class, 'class_id');
}
public function users()
{
return $this->belongsToMany(User::class);
}
public function members()
{
//this causes the problem!!
return $this->belongsToMany(User::class)->union($this->hasManyThrough(User::class,Student::class,'class_id','id','id','user_id'));
}
in User model relationship
public function group(){
return $this->belongsToMany(Group::class);
}
in Group model relationship
public function user(){
return $this->belongsToMany(User::class, 'user_group');
}
in Students model relationship
public function user(){
return $this->belongsToMany(User::class, 'user_id', 'id');
}
public function group(){
return $this->belongsToMany(Group::class, 'class_id', 'id');
}
you can call now
$users = User::whereHas('groups',function ($query){
$query->where('group_id',1);
})->get();
Sometimes you have two relations from one model to another, due pivot tables. In my example you could go from users to groups with the relation user_groups and the relation students. To get all users that belong to a certain group i need to call both relations. To solve this issue, i made use of Abdulmajeed's example to solve it. You can see the code below. Thanks for helping me out.
public function members()
{
return User::whereHas('groups', function($q)
{
$q->where('id',$this->id);
})->orWhereHas('students', function($q)
{
$q->where('class_id',$this->id);
});
}
my db table is
===batches ===
id
batch_title
===courses===
id
course_title
batch_id
===students ===
id
name
===course_student===
course_id
student_id
now i want to show how many students are join in this batch and also how many students in this course
my Student model
public function courses()
{
return $this->belongsToMany('App\Course');
}
Course Model
public function students(){
return $this->hasManyThrough('App\Course','App\Student');
}
public function batch() {
return $this->belongsTo('App\Batch','batch_id');
}
Batch Model
public function courses(){
return $this->hasOne('App\Course','batch_id');
}
You have many weakness in your code:
first to should rebuild your many to many relation between Course and Student according to many to many doc
Student Model
public function courses()
{
return $this->belongsToMany(Course::class);
}
Course Model
public function students()
{
return $this->belongsToMany(Student::class);
}
now: to get how many Student in this course:
$value = Course->withCount('students')->find($courseId);
$studentsCount = $value->students_count;
$students_count will have the student count for Course with id = $couserId
if you want to get Student Count for specific Batch will may walk in the same way:
$coursesInBatch = Course->withCount('students')->where('batch_id',$batchId)->get();
now $coursesInBatch holds the courses for this batch including there students_count
$studentCountInBatch = 0;
foreach ($coursesInBatch as $course) {
$studentCountInBatch += $course->students_count;
}
now $studentCountInBatch will hold how many student in Batch with id($batchId)
I have the following structure:
orders
id
name
products
id
name
items
id
order_id
product_id
quantity
The relationships are as follows:
Order
public function items(){
return $this->hasMany(Item::class)
}
public function products(){
return $this->hasManyThrough(Product::class, Item::class);
}
Item
public function order(){
return $this->belongsTo(Order::class);
}
public function product(){
return $this->belongsTo(Product::class);
}
Product
public function items(){
return $this->hasMany(Item::class);
}
I wish to get all products for the order doing something like this:
$order->items()->products()->get() using the hasManyThrough method, but I must be doing it wrong since it tries to look for item_id in the products table.
I realized that I do not need many through, I just need to use items table as a pivot table, defining the relationship on the Order model just like this:
public function products(){
return $this->belongsToMany(Product::class, 'items');
}
I am using Laravel 5.6. I am trying to query information from the grading_info table but I also want to return the students name and other info from the student_info table. I only want to return records in the grading_info table that are related to the currently logged in teacher. Currently its returning information for all teachers. I know I can add a where clause but I am trying to learn eloquent and was wondering if there was any way to accomplish this?
Teachers and students can have many enteries in the grading_info table and any teacher can grade any student.
I would like to return something like this
{
gradeID,
gradeDate,
gradeInfo
.....
student: {
studentName,
studentPhoneNumber,
studentEmail
......
}
}
users table (only stores teachers, not student)
id
teacher_info
teacherID (linked to id from users table)
student_info
id (auto increment. not relation to the users table)
grading_info
studentID (linked to id from student_info)
teacherID (linked to id from users)
User model
public function grades(){
return $this->hasMany(GradingInfo::class, 'studentID');
}
GradingInfo model
public function teacher(){
return $this->belongsTo(User::class, 'id', 'teacherID');
}
public function student() {
return $this->belongsTo(StudentInfo::class, 'studentID', 'id');
}
StudentInfo model
public function grades() {
return $this->hasMany(SessionInfo::class, 'studentID', 'id');
}
TeacherInfo model
// Nothing in here.
TeacherController
public function getGrades(Request $request)
{
$user = Auth::user(); // This is the teacher
$grades = $user->with('sessions.student')->orderBy('created_at', 'DESC')->get();
return response()->json(['sessions' => $sessions], 200);
}
You have Many to Many relationship between user(teacher) and student(student_info) tables
User Model
public function gradeStudents(){
return $this->belongsToMany(StudentInfo::class, 'grading_info', 'teacherID', 'studentID');
}
public function info(){ //get teacher info
return $this->hasOne(TeacherInfo::class, 'teacherID');
}
StudentInfo model
public function gradeTeachers(){
return $this->belongsToMany(User::class, 'grading_info', 'studentID', 'teacherID');
}
Now Fetch the data (TeacherController)
public function getGrades(Request $request)
{
$user = Auth::user(); // This is the teacher
$students = $user->gradeStudents; // it will return all graded students by logged in teacher
return response()->json(['students' => $students], 200);
}
Here grading_info is a pivot table for Many-To-Many relationship
for details check this https://laravel.com/docs/5.6/eloquent-relationships#many-to-many
Fetch Extra info from pivot table
If you want to add extra info in pivot table (grading_info) then add column (info) in this table and then need to change relationship like this
public function gradeStudents(){
return $this->belongsToMany(StudentInfo::class, 'grading_info', 'teacherID', 'studentID')
->withPivot('info')
->as('grade')
->withTimestamps();
}
Now if you fetch data
$user = Auth::user(); // This is the teacher
$students = $user->gradeStudents;
foreach($students as $student){
print_r($student);
print_r($student->grade->info);
print_r($student->grade->created_at);
}
I am new to this so bear with me.
I have 4 tables (users, scores, scorecards, courses) and I need to bring into a view info from all of these tables.
Here are the relationships:
Scores model
public function user(){
return $this->belongsTo('App\User');
}
public function scorecard(){
return $this->belongsTo('App\Scorecard');
}
public function course() {
return $this->belongsTo('App\Course');
}
Course model
public function club(){
return $this->belongsTo('App\Club');
}
public function scorecard(){
return $this->hasMany('App\Scorecard');
}
public function score() {
return $this->hasMany('App\Score');
}
Scorecard model
public function course(){
return $this->belongsTo('App\Course');
}
public function club(){
return $this->belongsTo('App\Club');
}
In my controller I get the scores id from a dropdown in the request. I need to essentially get the following info:
the scores record which is easy as i have the score id.
use the scorecard_id from the scores table to get the scorecard record from the scorecards table
grab the course info from the courses table using the course_id thats in the scorecards table.
You can eager load the relations using dot . as scorecard.course and it will load both scorecard and course.
$score = Score::with('scorecard.course')->find($id);
and then you can access corresponding attributes as:
$score->scorecard;
$score->scorecard->course;
if $id is the scores id from a dropdown,
$score=Score::with('scorecard','scorecard.course')->where(['id'=$id])->first();
then,
print_r($score);
gives the scores record.
print_r($score->scorecard);
gives the scorecard record.
print_r($score->scorecard->course);
gives the courses record.