Laravel - Eloquent Schema - Inheritance - php

This is what my schema looks like.
Schema:
User
id
email
password
firstname
lastname
Profile
user_id (foreign key)
name
weight
height
Model
I have a one to many relationship for the models.
User
class User extends Eloquent implements UserInterface, RemindableInterface {
public function Profiles()
{
return $this->hasMany('Profile');
}
Profile
class Profile extends Eloquent {
public function user()
{
return $this->belongsTo('User', 'user_id', 'id');
}
Problem
I realized that creating a separate name field in my Profile is already redundant to the firstname & lastname in User.
I plan to create a Profile property called name that is just referenced from the User model.
Any help on accomplishing this? Would appreciate any advice.
Thanks!

Related

Laravel many-to-many with 3 models

I have 3 models: Movie, Celebrity, Role. Each movie has many celebrities and each celebrity has many roles in many movies (for example the movie "Once Upon a Time" has celebrity "Quentin Tarantino" as roles ["Director","Writer"], and obviously "Quentin Tarantino" can have other movies performing different roles.
What is the best way to implement a many-to-many relationship between these 3 models, where we can easily access each movie's staff directly (like $movie->$roles->director)
Should we define a pivot table with movie_id, celebrity_id, role_id and a primary key of (movie_id, celebrity_id, role_id)?
class Movie extends Model{
public function movieCelebrityRole()
{
return $this->hasMany(MovieCelebrityRole::class);
}
}
class Celebrity extends Model{
public function movieCelebrityRole()
{
return $this->hasMany(MovieCelebrityRole::class);
}
}
class Role extends Model{
public function userRoleCompany()
{
return $this->hasMany(MovieCelebrityRole::class);
}
}
class MovieCelebrityRole extends Model{
public function movie()
{
return $this->belongsTo(Movie::class);
}
public function celebrity()
{
return $this->belongsTo(Celebrity::class);
}
public function role()
{
return $this->belongsTo(Role::class);
}
}
If you get a pivot table with more than two Foreign Keys, or have multiple many-to-many relationships, try to treat it as full model.
This also helps you to define more simple relationships.
Instead of Many-to-Many relationship. You can divide it into multiple of One-to-Many relationships.
E.g: In your case, you're going to have 4 models : Movie, Celebrity, Role, Program.
Movie hasMany Program.
Celebrity hasMany Program.
Role hasMany Program.
Program belongsTo Movie.
Program belongsTo Celebrity.
Program belongsTo Role.
For more details, check the Laravel documentation about the One-to-Many relationships :
https://laravel.com/docs/8.x/eloquent-relationships#one-to-many

Eloquent Update with One-to-One relationship

I am want to update my records in my database using Eloquent model. I am having an error in updating user_profile table that saying where id is not null.
User Model
class User extends Model
{
public function profile()
{
return $this->hasOne('App\Models\Common\UserProfile');
}
}
UserProfile Model
class UserProfile extends Model
{
public function user()
{
return $this->belongsTo('\App\Models\User');
}
}
Controller
$user->fill($data);
$user->save();
$user->profile->fill($data);
$user->profile->save();
In MySQL query it looks like this:
UPDATE users, user_profiles
SET users.name='Test Name',
user_profiles.email='test#gmail.com'
WHERE users.id=1
AND user_profiles.user_id=1;
I know MySQL query but I'm new to Eloquent and I want to do it in Eloquent model. Maybe there are some in here that can provide an explanation on how the magic works in Eloquent.
By default eloquent assumes, that any model has an id column as primary key. If that is not the case, you need to "register" the primary key with
protected $primaryKey = 'user_id';
in the model class.

Laravel foreign key relation

I've got a strange problem.
I've a users table and a company table. A User belongsTo a company and a company hasMany users.
Both primary keys of the table are id.
In the laravel documentation I read the following:
Additionally, Eloquent assumes that the foreign key should have a
value matching the id column of the parent.
I've got this in my CompanyModel:
protected $table = 'company';
public function users()
{
return $this->hasMany(UserModel::class);
}
When I try this:
$users = CompanyModel::find(1)->users;
dd($users);
It's not working. When I add a foreign key in my relation it works!?:
protected $table = 'company';
public function users()
{
return $this->hasMany(UserModel::class, 'id');
}
This is strange right? What on earth am I doing wrong.
--EDIT--
In my users table I've got a company_id column!
Firstly, I would suggest you rename your Model from CompanyModelto Company and from UserModel to User.
Then ensure you have company_id in your users table. And in your users migration file connect the users table with the companies table as such:
$table->integer('company_id')->unsigned();
$table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
Don't forget to refresh your database.
Then in your models, define the relationships as such:
// User model
// Laravel will automatically identify and use the `company_id` field in your reference
public function company(){
return $this->belongsTo(Company::class);
}
// Company model
public function users(){
return $this->hasMany(User::class);
}
You can then fetch your records in your controller as such:
$user = User::find(1);
$user_company = $user->company; // This might not be necessary in your controller, you can do it in your view
dd($users, $user_company);

How build a ternary relationship in Laravel 5

I have three entities:
User
Profile
Status
Summarized, users has a profile foreach status.
EXAMPLE
Users table records
user
id | name
1 user1
2 user2
3 user3
Status table records (this records is previously seeded)
status
id (PK) | title (string)
1 student
2 collaborator
3 teacher
Profile table structure
PROFILE
user_status_id (PK) (FK)
institution (string)
year (timestamp)
user1 is registered as student and fill your profile based on this status. After, he change your status to collaborator and fill another profile referred to this new status.
With that, i want to know:
When user1 was student?
the user1 was already collaborator ever?
Which institution user1 had frequented when he was student?
My first problem is:
How to model this relationship?
I'm not sure but think the above situation is a ternary relatinoship case, right?
And Second problem:
How build using Laravel Eloquent Relationships?
Let's start with relationship
class User extends Eloquent{
protected $table = 'user';
public $timestamps = true;
use SoftDeletingTrait;
public function status(){
return $this->hasOne(Status::class, 'user_id', 'id');
}
public function profile(){
return $this->hasMany(Profile::class,'user_id','id');
}
}
class Status extends Eloquent{
protected $table = 'status';
public $timestamps = true;
use SoftDeletingTrait;
public function user(){
return $this->belongsTo(User::class,'user_id','id');
}
}
class Profile extends Eloquent{
protected $table = 'profile';
public $timestamps = true;
use SoftDeletingTrait;
public function user(){
return $this->belongsTo(User::class,'user_id','id');
}
}
Above relation would somehow will get you what you need but just writing this relation made me question your table structure.
Suggestion DB Change For Better Relation
User
id, username, email, ........
Status
id, status, description, ........
Institutions
id, name, address, ............
User_Status_Institution
user_id,status_id,institution_id,timestamp,.......
This structure allows us that we can have Institution details even if there is no user_profile for that institution. Previous structure you had you can only have institution (name only) detail if and only if there is user profile. Also you can change institution (Name/address/phone etc) at one place and it will update it for all users.
As much as possible try that you can make information to be independent if possible because that reflects in models, object and relations.
Hope it makes sense.

Can't have multiple auth tables in Laravel, I want to use a link table in the database, need advice on creating link table

So basically I have 3 different types of users, all in their own table, however Laravel only allows me to use one table for authentication so I was thinking of making a link table in the database to hold the usernames and passwords from all the tables and use this table for logging users in.
My understanding of link tables is that they can only take the primary key from other tables so therefore I would only be able to get the usernames from each of my 3 tables into my link table, and not the passwords.
Is there a way that I can bring both the username and password fields into my link table? (& if possible the email fields too?, if not username and password is fine).
Thanks, Sam.
You can still have a users table and have separate tables for holding the other information, so you could do something like:
users(id, name, email, password, user_type_id)
user_types(id, name)
business_sellers(user_id, business_seller_columns...)
individual_sellers(user_id, individual_sellers_columns...)
admin(user_id, admin_columns...)
Then you can log your user in using the users table and then pull the relevant information from the other tables depending on the user_type
Or you could use polymorphic relationships and do:
users(id, name, email, password, role_id, role_type)
business_sellers(id, business_seller_columns...)
individual_sellers(id, individual_sellers_columns...)
admin(user_id, admin_columns...)
Then you models would look like:
class User extends Model
{
/**
* Get all of the owning role models.
*/
public function role()
{
return $this->morphTo();
}
}
class Admin extends Model
{
/**
* Get all of admins users.
*/
public function users()
{
return $this->morphMany('App\User', 'role');
}
}
class BusinessSeller extends Model
{
/**
* Get all of business_sellers users.
*/
public function users()
{
return $this->morphMany('App\User', 'role');
}
}
class IndividualSeller extends Model
{
/**
* Get all of individual_sellers users.
*/
public function users()
{
return $this->morphMany('App\User', 'role');
}
}
The you simply need to get your user and call role and the relevant model will be returned:
$user = App\User::find(1);
dd($user->role);

Categories