hello i'm trying to build school management system on secondary education and i have a ERM design i would Like to ask does laravel handle this type of relationship Many to many? please amend if i'm doing it wrongly since i'm a beginner thanks..
ERM
With 2 db tables many to many reationship
students(id,name,created_at,updated_at)
subjects(id, name, created_at,updated_at)
student_subjects(id, student_id, subject_id)
Models
class Student extends Model{
public function subjects(){
return $this->belongsToMany(Subject::class, 'student_subjects'); //here student_subjects is as a pivot table
}
}
class Subject extends Model{
public function stdents(){
return $this->belongsToMany(Student::class, 'student_subjects'); //here student_subjects is as a pivot table
}
}
Now Save data
$student = Student::find(1);
$student->subjects()->attach(2); // it will save subject 2 for student 1 in `student_subjects` table.
Note: similarly you can create relation for other models
For details check https://laravel.com/docs/5.6/eloquent-relationships#many-to-many
Related
In my app, you can create lists of roles that are attached to contacts. So you can assign the contact "Bob" the roles of "Gardener" and "Pet Sitter". Then you can create the list "People" and add "Gardener (Bob)" and "Pet Sitter (Bob)" to it.
I have the following tables:
contacts
id
name
roles
id
name
contact_role (pivot)
id
contact_id
role_id
lists
id
name
contact_role_list (pivot)
id
contact_role_id
list_id
Everything was working smoothly until the second pivot table linked to the first pivot table. My pivot tables are (currently) not having any models so I'm not sure if there is a built-in feature to tackle this in Laravel or if I need to think differently.
I currently have this in my List model:
public function list_roles(): BelongsToMany
{
return $this->belongsToMany(XYZ::class, 'contact_role_list', 'list_id', 'contact_role_id');
}
Is this even close? What do I put where it says XYZ::class?
Ok, so the below is doing what I want, but is there an even better way to do it? The key to solving my problem was to create a Model for ContactRole and changing extends Model to extends Pivot.
I placed this in my List Model:
public function list_roles(): BelongsToMany
{
return $this->belongsToMany(ContactRole::class, 'contact_role_list', 'list_id', 'contact_role_id');
}
And this in my ContactRole Model:
public function contact(): BelongsTo
{
return $this->belongsTo(Contact::class);
}
Now I could reach the contact data by using something like this: List::first()->contact_roles->first()->contact
Any way to use with, pivot or similar to tidy this up even more? Thanks!
I like to approach these issues in terms of Models rather than pivots. I think many new Developers in Laravel get over obsessed with what's going on in the Database which is fine, but theres a lot of Magic going on so you can write very simple code that does a lot of Heavy lifting, so that being said if I fully understand your problem
You have a Contacts Model
This model can have many roles
so in your contacts Model you need a role relationship
public function roles()
{
return $this->belongsToMany(Roles::class);
}
next of course you have a role Model (pun intended)
your each role can have many list
public function lists()
{
return $this->hasMany(List::class)
}
then the idea is now that you have roles on contacts and lists on roles you should be able to have many lists through contact
public function lists()
{
return $this->hasManyThrough(List::class, Role::class);
}
I've done similar things before and for your description it seems like that's the approach you might need to take.
I have an understanding issue with Laravel Eloquent Models and relations.
I have a user table user. These users can add car license plates, which I save in user_plates. I have a database which contains car models and types. The table name is cars. I have the models App\User, App\UserPlates and App\Car.
The user_plates table has the fields id,plate,user_id,car_id.
I save the plate, the associated user (in user_id) and the selected car (car_id (id from table cars))
I added plates() with belongTo function to my User Model which already successfully returns all plates associated with that user. But now I want to get the associated car (car_id inside user_plates). How do I achieve this using Eloquent? The car table does not have any connection to the user table, only user_plates has a car_id and a user_id.
I need to achieve this:
User -> Plates (can be multiple) -> Plate -> Car. I know how to achieve this using simple MySQL Joins but I want to do it right with Eloquent. Thanks for any help!
Laravel: 6.4.0
So, if your database is set up as...
users user_plates cars
----- ----------- ----
id id id
etc. plate etc.
user_id
car_id
Your models are set up as...
// in model: User
public function user_plates()
return $this->hasMany('UserPlate'); // fill out fully qualified name as appropriateā¦
// in model: UserPlate
public function user()
return $this->belongsTo('User');
public function car()
return $this->belongsTo('Car');
// in model: Car
public function user_plates()
return $this->hasMany('UserPlateā);
To return a collection of cars belonging to user $id you should be able to run:
$cars = User::findOrFail($id)-> user_plates->pluck('car');
I have a problem creating a "Double" n:m relation in Laravel.
First I have two tables called locations and services. These tables have a n:m relation and a table called location_service. The table has an incremental id and an id of each table.
In the Models I have the following Code:
class Service extends Model
{
public function locations(){
return $this->belongsToMany('app\Location','location_service','service_id','location_id');
}
}
class Location extends Model
{
public function services(){
return $this->belongsToMany('app\Service','location_service','location_id','service_id');
}
}
In addition, I created a table called tags. This table tag can be linked to several location_service and several location_service can be linked to different tags. I created a table called location_service_tag with an incremental id, the id of the location_service and the id of the tag. But how should I do the model? The point is, that there is no Model like app\Location_Service.
I am using laravel 5.1. The scenario is as follows(this is an example. The real scenario is similar to this example)
I have 3 models
College
Student
Teacher
A college can have many students but a student can belong to only 1 college.
A college can have many teachers but a teacher can belong to only 1 college.
I want to establish relationships between these tables in laravel.
One of the methods for this is to place a college_id foreign key on the Students and Teachers table. But in my case, this foreign key will be null a lot of times. So rather than have separate columns in 3-4 tables with mostly null values, I wanted to explore the option of having a polymorphic relationship for College table.
This is what I tried:
The example given in the laravel docs(link below) depict a one-to-many relationship whereas my scenario is more of a many to one relationship.
http://laravel.com/docs/5.1/eloquent-relationships#polymorphic-relations
As given in the example, having collegeable_id and collegeable_type columns on the College table would not have fulfilled my requirement as a college can contain many students/teachers so I created a pivot table:
Schema::create('collegeables', function (Blueprint $table) {
$table->integer('college_id')->unsigned();
$table->integer('collegeable_id')->unsigned();
$table->string('collegeable_type');
});
And I have the following models
College Model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class College extends Model
{
public function students()
{
return $this->morphedByMany('App\Student', 'collegeable');
}
}
Student Model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Student extends Model
{
public function college()
{
return $this->morphOne('App\Colleges', 'collegeable');
}
}
With this arrangement, I am able to store students using College model instance like this
$college = \App\College::find(1);
$student = new \App\Student;
$student->name = 'John Doe';
$college->students()->save($student);
But when I try to retrieve a College model instance using a student model instance as specified below, it gives me an error:-
public function index()
{
return \App\Student::find(1)->college;
}
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'colleges.collegeable_id'
This is kind of expected as morphOne works with columns in a table I suppose.
If I change the morphOne function in Student Model to morphToMany, the code starts working and I am able to retrieve values as well. But that make this relationship a many to many which again is not what I want.
So my question is this:-
Is their a morphSomething function I can use in the student model to be able to retrieve values for the student's college while maintaining the relationship as a one-to-many?
Any help would be really appreciated. Thanks.
There's no reason to use Polymorphic relationships here. Instead, just add a foreign key to your colleges table on both your students and teachers tables. Like this:
colleges
id
name
teachers
id
name
college_id
students
id
name
college_id
Then your models can use the belongsTo() and hasMany() relations, like so:
class College extends Model {
public function students() {
return $this->hasMany(App\Student::class);
}
public function teachers() {
return $this->hasMany(App\Teacher::class);
}
}
class Teacher extends Model {
public function colleges() {
return $this->belongsTo(App\College::class);
}
}
class Student extends Model {
public function colleges() {
return $this->belongsTo(App\College::class);
}
}
Polymorphic one-to-many relations are for the opposite of this relationship where you have a model that can only be related to a single record, but that record can be many different models.
Edit: To further explain why a polymorphic relationship isn't needed here, let's take a look at where it would be needed. Say you have a simple CRM style website. There are Customers and Projects and you want to have Comments on both. In this case, you would make Comments a polymorphic relationship because Comments belong to a single Customer or a single Project, but not both.
Your relationship is the exact opposite. In your case, Students and Teachers belong to a college. If you were to follow the previous example's pattern, a college would have belonged to a single student or teacher.
I had a similar need and managed to improvise in another way, taking advantage of morph's table structure.
You will need a Collegeable class to be Pivot (https://laravel.com/docs/9.x/eloquent-relationships#defining-custom-intermediate-table-models)
And then the magic:
public function college(){
return $this->hasOneThrough(Colleges::class,
Collegeable::class,
'collegeable_id',
'id',
'id',
'college_id',
);
}
And on the Collegeable Pivot class:
namespace App\Models;
use Illuminate\Database\Eloquent\Relations\Pivot;
class Collegeable extends Pivot
{
protected $table = 'collegeables';
}
So, I've been trying to watch and read eloquent relationships from laracasts. Unfortunately I still don't quite get how to translate database relationships to eloquent relationships (hasOne, belongsTo, hasMany, etc).
Let's say I have an Account and Customer tables. Account table has a "Customer_id" foreign key which references to the "id" on Customer table. Let's assume it's a one-to-many relationship. How should I put it on my models on laravel?
Which table should contain the "hasMany" and which one should have the "belongsTo"?
Just think about how you would say it. In your case it sounds like a Customer has many Accounts and an Account belongs to one Customer.
So you would put the hasMany() in your Customer model and the belongsTo() in your Account model.
class Customer extends Model {
public function accounts() {
return $this->hasMany('App\Account');
}
}
class Account extends Model {
public function customer() {
return $this->belongsTo('App\Customer');
}
}
You can read more about Laravel database relationships here.