How to deploy relationship in pivot of three model in laravel? - php

I'm developing a role and permissions based on laravel framework.
I have 3 models :
Weblog
User
Permissions
This is pivot table
user_id , weblog_id , permission_id
Now, a user can have a weblog with permission id 1,2 and another weblog with permission 1,2,3,4
How can I deploy relationships? and how can I check user permissions when managing a weblog. (middleware and ...)

With the fact that Permission are specific to Weblog
Say the pivot table is called permission_user_weblog
class User extends Model
{
public function weblogs()
{
return $this->belongsToMany(Weblog::class, 'permission_user_weblog');
}
public function permissionsFor(int $weblogId)
{
$permissionIds = null;
$this->weblogs()
->where('id', $weblogId)
->with('permissions')
->get()
->each(function($weblog) use(&$permissionIds) {
$permissionIds = $weblog->permissions->pluck('id');
});
return $permissionIds;
}
}
class Weblog extends Model
{
public function users()
{
return $this->belongsToMany(User::class, 'permission_user_weblog');
}
public function permissions()
{
return $this->belongsToMany(Permission::class, 'permission_user_weblog');
}
}
class Permission extends Model
{
public function weblogs()
{
return $this->belongsToMany(Weblog::class, 'permission_user_weblog');
}
}
Then you can check anywhere for whether logged in user has specific permission for a specific weblog
public function update(Request $request, $weblogId)
{
$user = auth()->user();
$permissions = $user->permissionsFor($weblogId);
//Check whether the logged in user has permission identified by id 1 or 4 for weblog
$can = !! $permissions->intersect([1,4])->count();
//Do rest of processing
}

your Weblog,User,Permission has ManyToMany Relation, its a kind of odd but if you want to have this kind of relation its not a problem.
just consider each pair a ManyToMany. and every one of those can have a hasMany to Pivot (i named it Access) too (based on your needs).
User model:
class User extends Model{
/**
* retrive weblogs
*
* #return BelongsToMany weblogs
*/
public function weblogs()
{
return $this->belongsToMany(App\WebLog::class,'accesses_table')
->withPivot("permission_id")
->using(App\Access::class);
}
/**
* retrive permissions
*
* #return BelongsToMany permissions
*/
public function permissions()
{
return $this->belongsToMany(App\Permission::class,'accesses_table')
->withPivot("weblog_id")
->using(App\Access::class);
}
/**
* retrive access
*
* #return hasMany [description]
*/
public function accesses()
{
return $this->hasMany(App\Access::class, "user_id");
}
}
Weblog model:
class Weblog extends Model{
/**
* retrive users
*
* #return BelongsToMany users
*/
public function users()
{
return $this->belongsToMany(App\User::class,'accesses_table')
->withPivot("permission_id")
->using(App\Access::class);
}
/**
* retrive permissions
*
* #return BelongsToMany permissions
*/
public function permissions()
{
return $this->belongsToMany(App\Permission::class,'accesses_table')
->withPivot("user_id")
->using(App\Access::class);
}
/**
* retrive access
*
* #return hasMany [description]
*/
public function accesses()
{
return $this->hasMany(App\Access::class, "weblog_id");
}
}
Permission model:
class Permission extends Model{
/**
* retrieve users
*
* #return BelongsToMany users
*/
public function users()
{
return $this->belongsToMany(App\User::class,'accesses_table')
->withPivot("weblog_id")
->using(App\Access::class);
}
/**
* retrieve weblogs
*
* #return BelongsToMany weblogs
*/
public function weblogs()
{
return $this->belongsToMany(App\Weblog::class,'accesses_table')
->withPivot("user_id")
->using(App\Access::class);
}
/**
* retrive access
*
* #return hasMany [description]
*/
public function accesses()
{
return $this->hasMany(App\Access::class, "permission_id");
}
}
and you can have a model for your pivot, which i named it Access :
Illuminate\Database\Eloquent\Relations\Pivot;
class Access extends Pivot
{
public $incrementing = true;
public function user()
{
return $this->belongsTo(App\User::class);
}
public function weblog()
{
return $this->belongsTo(App\Weblog::class);
}
public function permission()
{
return $this->belongsTo(App\Permission::class);
}
}

Related

Query on Pivot relation

I would like to query pivot model relation using Eloquent.
I've my User model :
class User extends Authenticatable
{
public function preferences(): BelongsToMany
{
return $this->belongsToMany(Preference::class, 'user_preference')
->using(UserNotificationPreference::class) //Custom Pivot model
->withPivot([enabled, channel_id]);
}
}
Here is the custom pivot model :
class UserNotificationPreference extends Pivot
{
/**
* The attributes that should be casted to native types.
*
* #var array
*/
protected $casts = [
'enabled' => 'boolean'
];
/**
* Channel relation.
*
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function channel(): BelongsTo
{
return $this->belongsTo(Channel::class);
}
}
And the preference model :
class Preference extends Model
{
// protected $connection = "apodis";
/**
* The users that belong to the preference.
*
* #return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function users(): BelongsToMany
{
return $this->belongsToMany(Preference::class, 'user_channel_notification_preference')
->using(UserNotificationPreference::class) //custom pivot
->withPivot(['preference_id', 'user_id', 'enabled', 'channel_id']);
}
}
From a User model, i would like to retrieve Preferences after querying custom pivot table relationship (Channel::class) ,
something like :
$user->preferences()
->wherePivot('enabled', true)
->whereHasPivot('channel', function(Builder $query) {
//doesn't exists
})->get()
There is a way to achieve this ?
(Products Model Laravel) public function products() {
return $this->belongsToMany('App\Product');
} (Shop Model Laravel)public function shops(){ return $this->belongsToMany('App\Shop');} you can specify the actual field names of that pivot table public function products(){ return $this->belongsToMany('App\Product','products_shops', 'shops_id', 'products_id');}possibility to get those values in our loops foreach ($shop-products as $product){echo $product->pivot->price;}

How can I belongTo (Store) depand on belongTo(Company)

I want to link these two BelongTo together so that when he chooses from (Company) he displays the (Store) related to his (company_id)
class User extends Authenticatable
{
/**
* Get the store
*
* #return BelongsTo
*/
public function store()
{
return $this->belongsTo(Store::class);
}
/**
* Get the company
*
* #return BelongsTo
*/
public function company()
{
return $this->belongsTo(Company::class);
}
}
and this is my resource User
public function fields(Request $request){
return[
BelongsTo::make(__('Company'), 'company', Company::class),
BelongsTo::make(__('Store'), 'store', Store::class)];
}
}

Laravel - Show all project from company that user is in

I have a system where I want to show all the projects from a company. That specific company must be the company that the logged-in user is in. This sounds relatively simple, but I can't figure out how with my current database setup because neither projects nor the user has a project_ID, this because I'm using an intermediate table. I've built my database structure like below
Users
company_id
Companies
id
Projects
company_id
Project_User
user_id
project_id
With the above setup, I made all the connections with every model except a model for Project_User. These models are listed below.
User model
class User extends Authenticatable
{
/**
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function role()
{
return $this->belongsTo(Role::class, 'role_id');
}
/**
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function job()
{
return $this->belongsTo(Job::class, 'job_id');
}
/**
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function company()
{
return $this->belongsTo(Company::class, 'company_id');
}
/**
* #return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function projects()
{
return $this->belongsToMany(Project::class);
}
public function isAdmin()
{
}
public function isCompanyOwner() {
if(Auth::check())
return(Auth::user()->job_id == 1);
return false;
}
}
Project model
class Project extends Model
{
/**
* #return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function users()
{
return $this->belongsToMany(User::class);
}
/**
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function company()
{
return $this->belongsTo(Company::class);
}
}
Company model
class Company extends Model
{
/**
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function users()
{
return $this->hasMany(User::class);
}
/*
*
*/
public function projects()
{
return $this->hasMany(Project::class);
}
}
How can I show all projects from the company that the logged user is in on my home screen? With this current DB setup?
The current Controller gets ALL projects and none particular from a specific company.
Controller
public function index()
{
$projects = Project::all();
return view('Project.show', compact('projects'));
}
Without getting technical, this would work:
$request->user()->company->projects;
Get the company for the current user then get the projects for that company.

Laravel: relations on same table

In my application I have a users table, in this table there is a field called managedByUsername which is the username of that particular user's manager.
To get your employees specifically you could perform a query as follows:
$employees = User::where('managedByUsername', auth()->user->username)->get()
To get your manager, on the User model you could have the relation;
public function mananager()
{
return $this->belongsTo(User::class, 'username', 'managedByUsername');
}
However, I can't think of how you would do this the other way around?
Perhaps
public function employees()
{
return $this->hasMany(User::class, 'username', 'managedByUsername');
}
But this obviously wouldn't work.
I have also tried the following:
/**
* Get the manager for this user
*
* #return void
*/
public function mananager()
{
return $this->belongsTo(User::class, 'managedByUsername', 'username');
}
/**
* Get the manager for this user
*
* #return void
*/
public function employees()
{
return $this->hasMany(User::class, 'managedByUsername', 'username');
}
The best approach to solve this problem would be to use the id of the user as the foreign key for manager.
So replace managedByUsername field with manager_id.
Then, you can write your Eloquent relations as:
public function mananager()
{
return $this->belongsTo(User::class, 'manager_id');
}
public function employees()
{
return $this->hasMany(User::class, 'manager_id');
}
Hope this helps to solve your problem.

How to update profile table on user registration

I have two tables: one for User and one for Profile.
I'm trying to figure out how to update the profile table upon a user registering.
Here's my User and Profile Model classes:
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface{
protected $fillable = array('fname','lname','email','password','create_at','updated_at');
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password');
/**
* Get the unique identifier for the user.
*
* #return mixed
*/
public function getAuthIdentifier()
{
return $this->getKey();
}
/**
* Get the password for the user.
*
* #return string
*/
public function getAuthPassword()
{
return $this->password;
}
/**
* Get the e-mail address where password reminders are sent.
*
* #return string
*/
public function getReminderEmail()
{
return $this->email;
}
/**
* #method to insert values into database.
*/
public static function create_user($data = array())
{
return User::create($data);
}
/**
*#method to validate a user in the database
*/
public static function validate_creds($data)
{
return Auth::attempt($data);
}
public function profile()
{
return $this->hasOne('Profile');
}
public function post()
{
return $this->hasMany('Post');
}
}
And my profile model:
<?php
class Profile extends Eloquent{
public static function createNewProfile($data)
{
return Profile::create($data);
}
public static function editProfile()
{
//
}
public function user()
{
return $this->belongsTo('User');
}
}
You can try events:
http://laravel.com/docs/events
Make a On.user.create event
and build a listener that does the things you need.
I'm not sure, but you could try to put that code that updates the Profile in the User Constructor.

Categories