BelongsTo in Laravel - php

I have a table which is named cars with 2 fields id, matriculation.
Then, I have another table which is named series with 2 fields id, name.
I have created my fk_serie on my table cars.
public function up()
{
Schema::create('cars', function (Blueprint $table) {
$table->increments('id');
$table->string('matriculation', 25);
$table->integer('fk_serie')->unsigned();
$table->foreign('fk_serie')->references('id_serie')->on('serie');
$table->timestamps();
});
}
Here is my information about the table series.
public function up()
{
Schema::create('series', function (Blueprint $table) {
$table->increments('id');
$table->string('name', 30);
$table->timestamps();
});
}
In my model, I only have a function on the model Car.
public function serie(){
return $this->belongsTo('App\Serie', 'fk_serie');
}
I don't have nothing in my model Serie
class Serie extends Model
{
//
}
Is it normal that the model Serie is empty?
Because, my join works.
What do you think ?
Is there an error?

As Dparoli mentioned in comments if you don't need the below query then your above structure of relationship is normal
Serie::with('cars')->find($id)
But if you want to setup relationship in Serie Model you can do something like below:
class Serie extends Model
{
public function cars() {
return $this->hasMany('App\Car', 'fk_serie'); // your relationship
}
}
And after that you can do:
$series = Serie::with('cars')->find($id); //eager loading cars
$cars = $series->first()->cars;

Related

Laravel: Order a model by "Has One Of Many" relationship

I have a customer model that has many contacts. I defined a relationship to get the most recent contact of the customer using the "Has One Of Many" relationship in Laravel 8:
Models
class Customer extends Model
{
use HasFactory;
public function contacts()
{
return $this->hasMany(Contact::class);
}
public function latestContact()
{
return $this->hasOne(Contact::class)->ofMany('contacted_at', 'max')->withDefault();
}
}
class Contact extends Model
{
use HasFactory;
protected $casts = [
'contacted_at' => 'datetime',
];
public function customer()
{
return $this->belongsTo(Customer::class);
}
}
Migration (contact model)
class CreateContactsTable extends Migration
{
public function up()
{
Schema::create('contacts', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->softDeletes();
$table->foreignID('customer_id');
$table->string('type');
$table->dateTime('contacted_at');
});
}
}
In my view, I want to show all customers and order them by their latest contact. However, I can't figure out how to do that.
I tried to achieve it via the join method but then I obviously get various entries per customer.
$query = Customer::select('customers.*', 'contacts.contacted_at as contacted_at')
->join('contacts', 'customers.id', '=', 'contacts.customer_id')
->orderby('contacts.contacted_at')
->with('latestContact')
Knowing Laravel there must be a nice way or helper to achieve this. Any ideas?
I think the cleanest way to do this is by using a subquery join:
$latestContacts = Contact::select('customer_id',DB::raw('max(contacted_at) as latest_contact'))->groupBy('customer_id');
$query = Customer::select('customers.*', 'latest_contacts.latest_contact')
->joinSub($latestContacts, 'latest_contacts', function ($join){
$join->on([['customer.id', 'latest_contacts.customer_id']]);
})
->orderBy('latest_contacts.latest_contact')
->get();
More info: https://laravel.com/docs/8.x/queries#subquery-joins
I suspect there is an issue with your migration, the foreign key constraint is defined like this:
Check the documentation:
https://laravel.com/docs/8.x/migrations#foreign-key-constraints
Method 1: define foreign key constraint
public function up()
{
Schema::create('contacts', function (Blueprint $table) {
$table->id();
$table->foreignId('consumer_id')->constrained();
$table->string('type');
$table->dateTime('contacted_at');
$table->timestamps();
$table->softDeletes();
});
}
Method 2: define foreign key constraint
public function up()
{
Schema::create('contacts', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('customer_id');
$table->foreign('customer_id')->references('id')->on('customers');
$table->string('type');
$table->dateTime('contacted_at');
$table->timestamps();
$table->softDeletes();
});
}

Booking system ala airbnb many to many laravel relationship?

I'm trying to create a system to log all bookings for a few airbnb hosts, at first I had two models Home and Guest, where a home can have many guests and a guest could book for many homes,
then I thought about creating a guest_home pivot table to link both tables... then things got complicated in my head, what about a Booking model, and (have that booking model act as a pivot table ?) , to me doing new Booking() seemed better than attaching ids to home model?
How could you guys go about this, it's making my brain malt right now...
I thought of doing something like this in my BookingController:
public function createBooking(Request $request)
{
$guestIds = Guest::latest()->take(3)->pluck('id');
$home = Home::findOrFail($request->input('home_id', 2));
$booking = new Booking();
$booking->home_id = $home->id;
$booking->guests()->attach($guestIds);
$booking->save();
return response()->json([
'booking' => $booking,
]);
}
Should I create home_guest pivot table, is a pivot table even needed? what models would I link, please bear with me, so far this is what I got:
Models
class Guest extends Model
{
public function bookings()
{
return $this->belongsToMany('App\Models\Home', 'bookings', 'guest_id', 'home_id');
}
}
class Home extends Model
{
public function guests()
{
return $this->belongsToMany('App\Models\Guest', 'bookings', 'home_id', 'guest_id');
}
public function bookings()
{
return $this->hasMany('App\Models\Booking');
}
}
class Booking extends Model
{
//Is Booking needed or I could make a pivot table like home_guest called 'bookings' ?
public function guests()
{
return $this->belongsToMany('App\Models\Guest', 'booking_guest', 'booking_id', 'guest_id');
}
}
Migrations:
Schema::create('bookings', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('home_id')->index();
$table->foreign('home_id')->references('id')->on('homes')->onDelete('cascade')->onUpdate('cascade');
$table->unsignedInteger('guest_id')->nullable()->index();
$table->foreign('guest_id')->references('id')->on('guests')->onDelete('cascade')->onUpdate('cascade');
$table->timestamps();
});
Schema::create('homes', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('host_id')->index();
$table->foreign('host_id')->references('id')->on('hosts')->onDelete('cascade')->onUpdate('cascade');
$table->string('fullAddress')->unique();
$table->integer('rooms')->unique();
$table->timestamps();
});
Schema::create('guests', function (Blueprint $table) {
$table->increments('id');
$table->string('fullName')->unique();
$table->string('identificationType')->unique();
$table->text('country')->nullable();
$table->timestamps();
});

student and teacher and course relationships in laravel

I have a problem with the relationships in my project in Laravel:
My project consists of:
Student (ID- Name - Mobile - Email)
Teacher (ID - Name - Mobile - Email)
Course (ID - Name - description)
Relationships :
Each course is offered by one or more teachers.
Each teacher offers one or more courses.
Each student enrolled in one or more courses.
Each student attended one or more courses at one teacher
Clarification :
course & teacher = (Many To Many).
course & student = (Many To Many).
student & teacher = (Many To Many).
Through my search I found:
Next two images .. Are these relationships true?
My Work:
- migrations:
Schema::create('courses', function (Blueprint $table) {
$table->increments('id')->unsigned();
$table->string('name');
$table->text('description');
$table->timestamps();
});
Schema::create('students', function (Blueprint $table) {
$table->increments('id')->unsigned();
$table->string('name');
$table->string('mobile');
$table->string('email');
$table->timestamps();
});
Schema::create('teachers', function (Blueprint $table) {
$table->increments('id')->unsigned();
$table->string('name');
$table->string('mobile');
$table->string('email');
$table->timestamps();
});
Schema::create('enrollments', function (Blueprint $table) {
$table->increments('id')->unsigned();
$table->integer('course_id')->unsigned();
$table->integer('student_id')->unsigned();
$table->foreign('course_id')->references('id')->on('courses')->onDelete('cascade');
$table->foreign('student_id')->references('id')->on('students')->onDelete('cascade');
$table->timestamps();
});
Schema::create('teaches', function (Blueprint $table) {
$table->increments('id');
$table->integer('course_id')->unsigned();
$table->integer('teacher_id')->unsigned();
$table->foreign('course_id')->references('id')->on('courses')->onDelete('cascade');
$table->foreign('teacher_id')->references('id')->on('teachers')->onDelete('cascade');
$table->timestamps();
});
Schema::create('student_course_teacher', function (Blueprint $table) {
$table->increments('id');
$table->integer('enroll_student_id')->unsigned();
$table->integer('enroll_course_id')->unsigned();
$table->integer('teach_teacher_id')->unsigned();
$table->foreign('enroll_student_id')->references('student_id')->on('enrollments')->onDelete('cascade');
$table->foreign('enroll_course_id')->references('course_id')->on('enrollments')->onDelete('cascade');
$table->foreign('teach_teacher_id')->references('teacher_id')->on('teaches')->onDelete('cascade');
$table->timestamps();
});
- models:
- Course:
class Course extends Model
{
protected $table = 'courses';
public function students()
{
return $this->belongsToMany(Student::class, 'enrollments', 'student_id', 'course_id')->withTimestamps();
}
public function teachers()
{
return $this->belongsToMany(Teacher::class, 'teaches', 'teacher_id', 'course_id')->withTimestamps();
}
}
- Student:
class Student extends Model
{
protected $table = 'students';
public function courses()
{
return $this->belongsToMany(Course::class, 'enrollments', 'course_id', 'student_id')->withTimestamps();
}
}
- Teacher:
class Teacher extends Model
{
protected $table = 'teachers';
public function courses()
{
return $this->belongsToMany(Course::class, 'teaches', 'course_id', 'teacher_id')->withTimestamps();
}
}
- Enrollment:
class Enrollment extends Model
{
protected $table = 'enrollments';
}
- Teach:
class Teach extends Model
{
protected $table = 'teaches';
}
Caution: I can not make relationships in (Enrollment & Teach).
My Requests:
Complete relationships
I want to get students for a certain course with teacher information.
I want to take courses with her students and teachers.
I want to get certain teacher courses with students.
Waiting for help,,
This is obviously not tested, but should help you figure out a solution towards your problem.
Name Of Tables
courses (For Course Model)
students (For Student Model)
teachers (For Teacher Model)
course_student (For Many To Many Relation between Student & Course) - For this you will create an extra model (CourseStudent), which will actually be used for Point 6.
course_teacher (For Many To Many Relation between Teacher & Course)
course_student_teacher (For Many To Many Relation between CourseStudent & Teacher)
Models
Course Model
class Course extends Model
{
public function students()
{
return $this->belongsToMany(Student::class)->withTimestamps();
}
public function teachers()
{
return $this->belongsToMany(Teacher::class)->withTimestamps();
}
}
Students Model
class Student extends Model
{
public function courses()
{
return $this->belongsToMany(Course::class)->withTimestamps();
}
}
Teachers Model
class Teacher extends Model
{
public function courses()
{
return $this->belongsToMany(Course::class)->withTimestamps();
}
// Courses/Students Currently Being Taught
public function courseStudents()
{
return $this->belongsToMany(CourseStudent::class, 'course_student_teacher')
->withTimestamps();
}
// List Of Students Currently Taught For Different Courses
public function allStudentsCurrentlyTaught()
{
return $this->courseStudents()->get()->map(function($courseStudent) {
return $courseStudent->student;
})->unique('id');
}
// List Of Courses Currently Taught To Different Students
public function coursesCurrentlyTaughtToStudents()
{
return $this->courseStudents()->get()->map(function($courseStudent) {
return $courseStudent->course;
})->unique('id');
}
// List Of Courses Taught To A Particular Students
public function coursesTaughtToAStudent($studentId)
{
return $this->courseStudents()->get()->where('student_id', $studentId)->map(function($courseStudent) {
return $courseStudent->course;
});
}
// List Of Students Taught For A Particular Course
public function coursesTaughtForACourse($courseId)
{
return $this->courseStudents()->get()->where('course_id', $courseId)->map(function($courseStudent) {
return $courseStudent->course;
});
}
}
CourseStudent Model for creating pivot table course_student_teacher
class CourseStudent extends Model
{
protected $table = 'course_student';
public function course()
{
return $this->belongsTo(Course::class)->withTimestamps();
}
public function student()
{
return $this->belongsTo(Student::class)->withTimestamps();
}
public function teachers()
{
return $this->belongsToMany(Teacher::class, 'course_student_teacher')->withTimestamps();
}
}

Implementing relationship in models

I have two models: Dish and DishCategory. I decided to implement a "One to many" relationship.
Here's a migration for Dish model:
Schema::create('dishes', function (Blueprint $table) {
$table->increments('id');
$table->string('dish', 50);
$table->string('photo');
$table->double('price', 8, 2);
$table->integer('category_id');
$table->integer('type_id'); /* 1 - menu for delivery; 0 - general menu */
});
And a migration for DishCategory model:
Schema::create('dish_categories', function (Blueprint $table) {
$table->increments('id');
$table->string('category');
});
I've created a method called dish() in DishCategory model:
public function dish()
{
return $this->hasMany('App\Dish');
}
And dish_category() in Dish model:3
public function dish_category()
{
return $this->belongsTo('App\DishCategory', 'category_id');
}
I'm trying to set up a foreign key in my relationship, so it's been set up in dish_category() method as a second parameter of belongsTo(). But it doesn't work. What is the workaround?
Change the dish() relationship definition to:
public function dish()
{
return $this->hasMany('App\Dish', 'category_id');
}
And dish_category() is defined correctly.
If you also want to add a constraint, add this to the dishes table migration:
Schema::table('dishes', function (Blueprint $table) {
$table->foreign('category_id')->references('id')->on('dish_categories');
});

Laravel: One to Many Or Polymorphic Relation for Different Content types?

I have a table contents which has many types, for example posts , albums, videos.
the contents table migration is :
Schema::create('contents', function (Blueprint $table) {
$table->increments('id');
$table->integer('ref_id')->index();
$table->integer('type')->index();
$table->string('title', 255);
$table->text('description');
$table->boolean('published')->default(false);
$table->string('thumb', 255);
$table->timestamps();
});
and posts table migration is:
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->text('body');
});
the same idea goes for all other types like videos:
Schema::create('videos', function (Blueprint $table) {
$table->increments('id');
$table->string('youtube_id', 255);
});
To retrieve the full content now, I use hasMany relationship:
class Content extends Model
{
public function posts() {
return $this->hasMany('App\Post','id' ,'ref_id');
}
public function videos() {
return $this->hasMany('App\Video','id' ,'ref_id');
}
...
}
class Post extends Model
{
public function content() {
return $this->belongsTo('App\Content', 'id' , 'ref_id')->where('type','1');
}
}
class Video extends Model
{
public function content() {
return $this->belongsTo('App\Content', 'id' , 'ref_id')->where('type','3');
}
}
As you can see, I manually added types where each type has a number , for example, content with type 1 is for posts, content with type 3 is for videos, etc..
I feel like my structure isn't that good and can be improved. I came across Polymorphic Relations in the documentation and I don't know if it will be good for my case or not.
Any Advice?

Categories