making model relationship to user, user can only access its own data - laravel

i have 2 main models and some child models with relationController to main models, now i need to add user id to both main and child models so user can only access its own data since users data stay on the same table.
i create belongsToMany relationship from user.php to the models and vice versa with pivot table but nothing happen
i have no idea how to do this since i need simplified database management in case i need to do migration..
can someone share your experience on this..

I can suggest you that you just add user_id [for Backend => backend_users_id ] to models which data you want access to owner only.
now in main model you can define belongsTo relation and in user you can define hasMany relation
main model relationship [if you want to restrict the user in backend side then you need to add backend user relation and same in backend user model]
class MainModel extends Model
{
// Adding relation to user model
public $belongsTo = [
'user' => 'RainLab\User\Models\User',
'backend_users' =>'Backend\Models\User' // for Backend
];
}
adding a relation to the user model [ you need to put this code in your plugin's boot method ]
// Extending User Model
\RainLab\User\Models\User::extend(function($model) {
$model->hasMany['mainmodel'] = ['HardikSatasiya\Plugin\Models\MainModel'];
});
// for Backend users
\Backend\Models\User::extend(function($model) {
$model->hasMany['mainmodel'] = ['HardikSatasiya\Plugin\Models\MainModel'];
});
Now access data [ Front-end side ]
// Returns the signed in user
$user = \Auth::getUser();
dd($user->mainmodel); // it will return collection of related mainmodels
// it will return related data and now its filter by owner
dd($user->mainmodel[0]->otherRelatin);
// for Backend users
// Returns the signed in user
$user = \BackendAuth::getUser();
dd($user->mainmodel); // it will return collection of related mainmodels
// it will return related data and now its filter by owner
dd($user->mainmodel[0]->otherRelatin);
Example filter data in listview based on logged in admin user [ OctoberCMS do not give such functionality out of the box, you can not hide a portion of data records you can hide entire menu or all records based on rights and roles but can not hide partial records ]
public function listExtendQuery($query)
{
$user = \BackendAuth::getUser();
$query->where('backend_users_id', $user->id);
}
to add backend_users_id you can use this code
class MainModel extends Model {
public function beforeSave()
{
$user = \BackendAuth::getUser();
$this->backend_users_id = $user->id;
}
}
if any doubt please comment.

Related

Laravel custom or extended belongsToMany

I have a table 'users' and a table 'groups'.
In the application, i am working on, the administrator can assign groups to users.
So there is a many-to-many relationship between these tables.
With the following code i defined this relation:
public function groups()
{
return $this->belongsToMany('\App\Group');
}
This way i can retrieve the groups this user is assigned to:
$users = User::with('groups')->get()
But above this, settings in the application provide the posibility to set a group for all the users.
Is it possible to define a relation so that i retrieve all groups that are related to the user plus the one that is assigned to all users according to the setting? Something like this:
public function groupsInclDefaultGroup()
{
$defaultGroupId = Setting::getSetting('defaultGroupId');
return $this->belongsToMany('\App\Group')->..??..($defaultGroupId);
}
.
$users = User::with('groupsInclDefaultGroup')->get();

how to show authenticated user data from relations

I'm trying to show the data of the authenticated user from his relation with other tables but can't get it to work, and I'm pretty new to laravel.
the user table has a relation with level table thru level_id, and the level table has a morph relation with the languages table, I'm trying to show the language of the level of the current user
here is my user model relation
public function level()
{
return $this->belongsTo(Level::class, 'level_id');
}
and my level model
public function languages()
{
return $this->morphMany(Language::class, 'langable');
}
and in the language table, I need to get back the title of 0 or 1 like
languages['0']title.
here is my controller
public function profile()
{
$user= User::with('level')->with('offers')->get();
return view('pages.user.index',compact('user'));
}
and here is how I got the auth user
{!! auth()->user()->first_name . ' ' . auth()->user()->last_name !!}
I'm trying to get this to work
{{auth()->user()->level()->languages()->title['0']}}
but it shows me this
Try {{ $user->level->languages->title['0'] }} in your index.blade file since you are passing the $user var from your controller to it. Currently you are using the user from session.
i got the answer guys it goes like this
{{Auth::user()->level->languages[0]->title}}
that'd show the level of the current user
Okay, there are a few steps you need to get done
in your controller:
public function profile()
{
$user = Auth::user(); // gets the logged in user
return view('pages.user.profile', compact('user')); // return view with $user variable
}
in your user model add:
// appends the level data to the $user model
// so every time you retrieve a user, the level data is included and accessible
// after that you can use $user->level in your view file
protected $appends = [
'level'
];
in your level model add:
// appends the languages data to the $user model
// so every time you retrieve a level, the languages data is included and accessible
// after that you can use $level->languages in your view file
protected $appends = [
'languages'
];
NOTE: In Step 3 you are retrieving multiple languages for a level. Is that correct ?
usage in view
$user->level->languages[specificLanguage]->title // if level has multiple languages
$user->level->language->title // if level has one language

Laravel Nova: BelongsToMany. Displaying list on details page based on a condition (from db)

I am developing a Web application using Laravel Nova. Nova is quite a new CMS system for Laravel. What I am now having trouble with many to many relationship and presenting data.
I have a users table with the following data
users - id, name, email, role
Then I have a departments table with the following data.
departments - id, name, code
They have many-to-many relationship with a pivot table like this.
departments_users - id, department_id, users_id
In the User resource if I added this in the fields method
public function fields(Request $request)
{
return [
ID::make()->sortable(),
//other fields
BelongsToMany::make("Departments")
];
}
Because of I added BelongsToMany in the User resource, if I go to the user details page, I will see something like this.
Basically what I mean is the option to display list of departments of users and option to attach departments to user. But I do not want to display that option/list all the time. I only want to display it based on the role. I mean something like this in the fields method. Please, read the comment in the following code.
public function fields(Request $request)
{
return [
ID::make()->sortable(),
//other fields
BelongsToMany::make("departments")//Do this only if the user role is "staff"
];
}
This is simple to achieve using laravel nova authorization.
You can add ->canSee() to BelongsToMany field.
You didn't specified which user has to have role "stuff". Logged in or edited.
If logged then just make:
BelongsToMany::make("departments")
->canSee(function ($request) {
return $request->user()->role == 'stuff';
}),
If edited user:
BelongsToMany::make("departments")
->canSee(function ($request) {
return $this->role == 'stuff';
}),
For more info check Field Authorization docs

How to relate additional tables to Auth::user

On documentation of Laravel, to retrieve the authenticated user:
$user = Auth::user();
This is my table schema (example)
tblUser
id // 1
userid // admin
password // 12345
tblUserInfo
id // 1
userid // admin
first_name // Roi
Is it possible to relate the tblUserInfo for the authenticated user? like for example
Auth::user()->with('userinfo')->first_name;
or is there a way around to get the first_name from authenticated user before I hit the view?
You should be able to just do
$firstname = Auth::user()->userinfo->first_name;
This assumes you have your relationship defined properly. Something along the lines of
class User extends Authenticatable
{
// ...
public function userinfo()
{
return $this->hasOne(UserInfo::class);
}
}
Given your non-standard table schema you may need to explicitly specify column names for foreign and local keys in hasOne() method - 2nd and 3rd parameters accordingly.
return $this->hasOne(UserInfo::class, 'id', 'id'); // or 'userid' depending on what you're using as a FK
^^^^^^^^^

How to check if a model instance is attached to related model instance in laravel 5.3?

I have many to many relation for roles and permissions models. I have an action controller for attaching and detaching permissions from users. How to check if some permission is detached to some role?
controller:
class RolePermissionController extends Controller
{
// POST /roles/1/permissions/2/sync
// BODY {isAllowed: true}
// $role - instance of role model with id == 1
// $permission - instance of permission model with id == 2
// roles and permissions has many to many relationship
public function synchronize(Request $request, Role $role, Permission $permission)
{
$this->authorize($permission);
$this->validate($request, [
'isAllowed' => 'required|boolean'
]);
// I want to check here if the permission is attached to the role
if ($request->input('isAllowed')) {
$role->perms()->attach($permission);
} else {
$role->perms()->detach($permission);
}
}
}
I simply use the association method of the first model to gain access to a query builder for the join table, then ask for the count of the associated model's column. In your case, I think:
$role->perms()->where('permission_id', $permission->id)->count() > 0
$role->whereHas('perms', function($query) use($permission) { $query->where('perms.id', $permission->id); })->count();
Alternatively, say if you already had the permissions loaded:
$role->perms->contains(function($value) use($permission) { return $value->id == $permission->id; })

Resources