Eloquent Laravel , Superior and Subordinate relationship - php

I have a project in laravel ,
It is an online library in which there can be three types of users , superAdmin
writersAdmin and writers,
I have already created the roles and permissions successfully
but i want to have superiors and subordinates kind of relationship in the users table
for example , the writersAdmin can have multiple writers that work for him,
is it possible to do so in the users table only or do i have to create other tables.

It can be achieved only in the user table.
for example, add superior_id column, and the save superior's id.
And, add the following code to the user model.
class User extends Eloquent {
protected $table = 'users';
public $timestamps = false;
public function parent()
{
return $this->belongsTo('User', 'superior_id');
}
public function children()
{
return $this->hasMany('User', 'superior_id');
}
}
How to use
User::with('parent')->find(1);
User::with('children')->find(1);
but, if there is more than one superiors in the user, can not be achieved in this method.
In that case, I recommend you to create other table.

Related

Laravel get school users

I am making a project that will have schools that are already seeded into the database, one user has one school.
User table has school_id
I made this relationship:
User.php
public function school(){
return $this->belongsTo('App\Models\School');
}
School.php
public function user()
{
return $this->hasMany('App\Models\User', 'school_id');
}
When i do
$school = School::where('id', 1)->first();
dd($school);
I get every field from the school model but the users aren't there,how do i make that the users appear there too without having to do?
dd($school->user)
You should use the Eloquent feature called Eager Loading
So, to eager load all the users, you should do:
School::with('user')->get();
Alternatively, if you are willing to automatically load the user without having to specify with(‘user’) every time, you can set the $with property in your School model like this:
protected $with = [‘user’];
Nvm I fixed it by doing this query
$schools = School::with('user')->get();

Laravel Eloquent relationship Many to Many

A user can have one whitelabel.
A whitelabel can have many users.
I have a pivot table with whitelabel_id, and user_id columns
I have both relationships set up using ->belongsToMany() (with the inverse).
I am using a pivot table because I don't have a whitelabel_id on the users table (and won't be putting one in) so its defined as a many-to-many, but really it's one-to-many. I just get the first() whitelabel as there'll only be one for each user.
With this in mind. How do I select * users with the currently authenticated user's whitelabel?
I have this, it works, but is this the "Laravel" way? I feel it's slightly over engineered and Laravel would have a shorthand method.
$user->when(auth()->user()->whitelabel->first(), function ($query) {
return
$query->whereIn('id', auth()->user()->whitelabel->first()->users->pluck('id'));
})
This checks if the auth user has a whitelabel, and then gets all users with the same whitelabel.
Does Laravel have a quick shorthand for this?
Models:
class Whitelabel
{
public function users()
{
return $this->belongsToMany(User::class);
}
}
class User
{
public function whitelabels()
{
return $this->belongsToMany(Whitelabel::class);
}
}
you can retrieve records for simple
$user = User::find(Auth::id())
$user->whitelabels
if you want return all user in Auth user's whitelabel
foreach($user->whitelabels as $whitelabel){
$whitelabel->users
}

Laravel eloquent model - get rows using intermediate table

I have 3 tables users, posts and photos.
post table has one - one relation to photos & users like, post.user_id=users.id and post_photo_id=photos._id.
I use
public function posts(){
return $this->hasMany('Post');
}
and I get all the posts by user using $user->posts().
What I need is to get all the photos by user, something like $user->photos.
SELECT photos.*
FROM photos
JOIN posts ON posts.photo_id=photos.id
JOIN users ON users.id=posts.user_id
WHERE user_id=1
Note: photos table has just 2 fields, id & photo.
In your User model, create a relationship like
Class User Extends Model
{
...
public function photos()
{
return $this->hasManyThrough('Photos','Posts','photo_id','id');
// Params (all strings): Final Model, Intermediate Model, Intermediate Model Key (posts), final Model Key (your photos)
}
public function Posts()
{
return $this->hasMany('Posts');
}
...
}// end class
Then in your controller, you'll just call your data with the relationships. This assumes you're hinting, but you get the idea...
$picturesByUser = $this->user->with(['posts','photos'])->find($id);
finally, in your blade, just eager load them...
#foreach(...)
$user->photos->pathToPicture;
$user->posts->pictureTitle;
#endforeach
Straight out of the Laravel Docs

Laravel 5 Relations

Database Structure:
-Users Table
-user_id
-name
-...
-Follow Table
-user_id
-follow_id
so when user follow another it will be inserted in follow table
and when get user followers
$user = User::where('user_id',$id)->first();
$user['followers'] = $user->Followers;
$user['following'] = $user->Following;
return $user;
By This Relation in User Model Side
public function Followers()
{
return $this->hasMany('App\Follow','follow_id','user_id');
}
And By This Relation in Follow Model Side
public function getUserData()
{
return $this->belongsTo('App\User','user_id','user_id');
}
It Works Fine for me and it gaves me every id But the problem is
that i want to get information about every user returned from this relation
so i should call User Model for each user returned to get his information
or what ??
The way you have you many-to-many relationship set up is almost right.
Firstly, change the Followers() method to be followers() as Laravel follows the PSR-2 standard.
Secondly, this isn't essential but change the user_id column in the users table to be just id. This is a laravel convension that does not need to be followed, however, at this point I don't see any reason not to follow it. I am assuming that you have something like:
protected $primaryKey = 'user_id';
in your User model. If you change your user_id column to id you won't have to have the above declaration anymore.
(If you don't have that line in and you want to continue using user_id as the primary key you WILL have to add that line to your User model.
Thirdly, change the relationship type in followers() to be:
public function followers()
{
return $this->belongsToMany('App\User', 'follower', 'user_id', 'follow_id');
//follower is the table name, user_id is column that relates to the current model and follow_id is the column that is for the relationships
}
With all of the above done you can now get a user with all of their followers by doing:
$user = User::with('followers')->find($id);
This will allow you to get the followers by simply doing:
$user->followers
At this point you can not get rid of you Follow model as you generally wont need a model for a pivot table.
To get the following relationship just add:
public function following()
{
return $this->belongsToMany('App\User', 'follower', 'follow_id', 'user');
}
to your User model.
Again to access this you can either:
$user = User::with('following')->find($id);
or if you have already have the user model and the relationship isn't loaded you can:
$user->load('following'); //in this case following is the name of the method where you have declared the relationship.
For more information please refer to the documentation http://laravel.com/docs/5.1/eloquent-relationships#many-to-many and http://laravel.com/docs/5.1/eloquent
Hope this helps!

Laravel: How do I create a custom pivot model?

I'm working on a project that has a many to many relationship between User and Club. This relationship works and I can get the respective objects with: $user->clubs. The pivot table I've named memberships. I can get the pivot data with $club->pivot. Foreign keys are defined for the memberships table in migrations.
However, I'd like the pivot table to be represented by a model so that I can easily update attributes of Membership such as role (Or even add a Role model to Membership!) or status.
I've looked at "Defining A Custom Pivot Model" in the docs, but what it says doesn't work for me, I get:
ErrorException
Argument 1 passed to Illuminate\Database\Eloquent\Model::__construct() must be of the type array, object given
I've also looked at this description of how to do it, but it's more or less the same as above.
Membership model:
class Membership extends Eloquent {
protected $table = 'memberships';
public function user()
{
return $this->belongsTo('User');
}
public function club()
{
return $this->belongsTo('Club');
}
}
Has anyone done this before?
This has been solved by a suggestion by a reddit user to extend Pivot in my Membership model. I also had to add ->withPivot('status', 'role')->withTimestamps() to the relationship declarations in the User and Club models.
You can do this by adding some manual code.
Your Membership model looks ok. You can get all clubs of a $user easily if you define method $user->clubs() where you get all the clubs manually.
clubs() {
$memberships=$this->memberships;
$clubs=new \Illuminate\Database\Eloquent\Collection();
foreach($memberships as $m) {
$clubs=$clubs->merge($m->clubs);
}
return $clubs;
}

Categories