How to authorization user in laravel? - php

I have user table :
| id | username | password | role_id |
|:--:|:--------:|:--------:|:-------:|
| 1 | user1 | password | 10 |
| 2 | user2 | password | 11 |
and the role table :
| id | name |
|:--:|:----:|
| 10 | admin|
| 11 | superadmin|
it is mean the user table should has relationship with role table.
I get confused how to make authorization with relation table, I have try to include this method in my user model, but is not working :
public function role()
{
return $this->belongsTo(Role::class, 'role_id', 'id');
}
and this is my Gate in authserviceprovider :
public function boot()
{
$this->registerPolicies();
Gate::define('isSuperadmin', function ($admin) {
return $admin->role == 'superadmin';
});
}

When you go $admin->role it will return a model instance of the role, which is not a string, you should have
$admin->role->name === 'superadmin'
And a side note it makes more sense to me to call the admin var $user since it might be a regular user

Use spatie/laravel-permission package instead for roles/permissions management.

Related

Laravel Relationship - Additional fields in pivot table linking to additional models

I have simplified the problem to get to the point. I have three tables, users, roles, account.
Normally I would set up the User model to have a many to many relationships with roles but I want those roles to be specific to each account. So I have added an additional field to the pivot table. Here are the tables and fields that I have;
‘users’ table
|—————————
| id | name |
|—————————
| 1 | Bob |
| 2 | Jim |
| 3 | Fred |
|—————————
‘roles’ table
|—————————
| id | title |
|—————————
| 1 | Administrator |
| 2 | Manager |
| 3 | Approver |
|—————————
‘accounts’ table
|—————————
| id | name |
|—————————
| 1 | ABC Company |
| 2 | XYZ Shipping |
| 3 | KLM Transport |
|—————————
I then have the pivot table role_user with an additional pivot field for the account;
|—————————
| role_id | user_id | account_id
|—————————
| 1 | 3 | 1
| 2 | 2 | 1
| 3 | 2 | 3
| 3 | 1 | 2
|—————————
I have used the withPivot function on the belongsToMany function when setting up the many to many relationships. This allows me to get the information using $user->roles->pivot->account_id but what I need is to be able to get the name of that company. All it’s passing to the blade template is the id from the pivot table and not linking that to an actual Account model.
Is there a way with Eloquent to get this entire model in the same way as the original relationship?
Create a Custom Pivot Model
use Illuminate\Database\Eloquent\Relations\Pivot;
class RoleUserAccountPivot extends Pivot
{
public function user()
{
return $this->belongsTo(User::class);
}
public function role()
{
return $this->belongsTo(Role::class);
}
public function account()
{
return $this->belongsTo(Account::class);
}
}
Update your belongsToMany relationships
Bellow is an example with the User::roles relationship
class User //extends...
{
public function roles()
{
return $this->belongsToMany(Role::class, /*other parameters*/)->using(RoleUserAccountPivot::class)->withPivot('account_id');
}
}
Usage
$user->roles->first()->pivot->account // returns Account model
Hope it helps.
Reference links:
Laravel doc on custom pivots

How to Create Relation in Eloquent Relationships Laravel

I have Two Table
1- projects
User with id 5 has created 3 project - which means he will have 3 unique conversation with our different agent
----------------------------------------
|id | user_id | title | time |
|1 | 5 | Example | 2018-06-30 |
|2 | 5 | Example | 2018-06-30 |
|3 | 5 | Example | 2018-06-30 |
----------------------------------------
2- conversation
-------------------------------------------
|id | project_id | user_one | user_two |
|1 | 1 | 5 | 3 |
|2 | 2 | 5 | 7 |
|3 | 3 | 5 | 10 |
-------------------------------------------
Whenever a project is created, a conversation is created with that project id, Now in Laravel i want to get that project detail using Eloquent Relationships.
User_one is the project creator and user_two is our agent assigned to that product.
This is What I've tried
class Chat extends Model {
public function project()
{
return $this->belongsTo('App\ProjectModel');
}
}
class ProjectModel extends Model
{
public $table = 'projects';
}
Here is the controller function
public function Progress($id){ // Id passed here is 2, so it should show detail of project number 2
return \App\Chat::find($id)->project()->get();
}
After all this I'm getting an error - Call to a member function project() on null
You can try like this with creating 2 Models Project and Conversation
table
conversations(id, project_id, creator, agent)
Project Model
public function conversations(){
return $this->hasMany('App\Conversation');
}
Conversation Model
public function project(){
return $this->belongsTo('App\Project', 'project_id');
}
public function creatorUser(){
return $this->belongsTo('App\User', 'creator');
}
public function agentUser(){
return $this->belongsTo('App\User', 'agent');
}
Fetch Data
public function Progress($id){ // Id passed here is 2, so it should show detail of project number 2
$chats = Conversation::with('project', 'creatorUser', 'agentUser')->where('project_id', 2)->get();
foreach($chats as $chat){
dd($chat->project); //it will always print same project because we have filter the conversation by project_id
dd($chat->creatorUser);
dd($chat->agentUser);
}
}
you can create a relation Along with specifying foreign Key and owner key like:
class Chat extends Model {
public function project()
{
return $this->belongsTo(App\ProjectModel::class, 'project_id', 'id');
}
}
and then you will be able to get:
\App\Chat::where('id', $id)->first()->project;

Spatie Laravel-activitylog causedBy, performedOn with Logging model

I am using this package for activity logging in laravel
I am able to do logging from controller but, I want to do it using Model.
I read this useful information from the official documentation
but, it doesnt store subject id, type and causer id, type. I can store it from controller as
activity()
->causedBy($userModel)
->performedOn($someContentModel)
->log('edited');
How to do this from model? Suggestions are appreciated.
Alright. Now I got your question. If you want to performance in Modal.
Below is my sample code in my Business model class.
protected static function boot()
{
//to log what field update
static::updating(function ($business) {
$changes = $business->isDirty() ? $business->getDirty() : false;
if($changes)
{
foreach($changes as $attr => $value)
{
activity()
->performedOn($business)
->causedBy(auth()->user())
->withProperties(['business_name' => $business->name, 'which field updated' => $business->getDirty()])
->log('Business Field <span class="text-green">Updated</span> - '.$business->name);
}
}
});
}
For the Subject's info you have to manually add in, below is my sample code how I store it in controller. I hope you can get some reference.
activity()
->performedOn($business)
->causedBy(auth()->user())
->withProperties(['business_name' => $business->name)
->log('Business <span class="text-green">Updated</span> - '.$business->name);
DB Records as below:
+----+----------+-----------------------------------------------------------------+------------+--------------+-----------+-------------+-------------------------------------+---------------------+---------------------+
| id | log_name | description | subject_id | subject_type | causer_id | causer_type | properties | created_at | updated_at |
+----+----------+-----------------------------------------------------------------+------------+--------------+-----------+-------------+-------------------------------------+---------------------+---------------------+
| 1 | default | Business <span class="text-green">Updated</span> - Companies 10 | 10 | App\Business | 1 | App\User | {"business_name":"Best Restaurant"} | 2017-08-04 14:58:06 | 2017-08-04 14:58:06 |
+----+----------+-----------------------------------------------------------------+------------+--------------+-----------+-------------+-------------------------------------+---------------------+---------------------+

Laravel 5.5 User model and friends relationship (belongsToMany) by multiple columns

Problem
I created a simple friendship relationship for my Laravel app which all worked ok until I noticed that when I queried the friendship of a user it would only search the current user on the UID1 field.
Since friendships are in essence a two-way relationship, Im trying to find a way in a laravel Model to retrieve ALL friendships relations by multiple columns.
Current Implementation
public function friends()
{
return $this->belongsToMany( App\Modules\Users\Models\User::class ,'friends', 'uid1');
}
Ideal Implementation
public function friends()
{
$a = $this->belongsToMany( App\Modules\Users\Models\User::class ,'users_friends', 'uid1');
$b = $this->belongsToMany( App\Modules\Users\Models\User::class ,'users_friends', 'uid2');
return combine($a,$b);
}
Table Structure
+----------------------+
| users table |
+----------------------+
+----| id: primary UserID |
| | fname: string |
| +----------------------+
|
|
| +----------------------+
| | friends table |
| +----------------------+
| | id: primary iD |
| | |
+----| uid1: user_id |
| | |
+----| uid2: user_id |
+----------------------+
The current implementation will only result in 1 of these records returning if the Current UserID = 1 as per the data in the friends table below.
+-------------------------------+
| friends table (data) |
+--------|---------|------------+
| id | uid1 | uid2 |
+--------|---------|------------+
| 1 | 1 | 7 |
| 2 | 7 | 1 |
| 3 | 9 | 1 |
+-------------------------------+
User Model
<?php
namespace App\Modules\Users\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected $table = 'users';
protected $fillable = [
'username', 'email', 'password', .... .
];
public function friends()
{
return $this->belongsToMany( App\Modules\Users\Models\User::class ,'users_friends', 'uid1');
}
Environment
Server = Homestead/linux
PHP = 7
MySQL
Update
I have a FriendShip helper class I created which does something similar, however in this function I pass in the UserID explicitly
Friendship::where( [
[ 'uid1' ,'=', $uid],
])->orWhere( [
[ 'uid2', '=', $uid]
])->all();
You can add additional conditions when you're declaring relationship by simply chaining it.
<?php
//...
class User extends Model {
//...
public function friends() {
return $this->hasMany(/*...*/)->orWhere('uid2', $this->id);
}
//...
But keep in mind that eloquent is not grouping the first conditions of relation in parenthesis so you might end with SQL that will not work as expected in some cases (if using or, and should be fine)
For example the above might result in a SQL that looks like this
SELECT * FROM users_friends WHERE uid1 = ? AND uid1 IS NOT NULL OR uid2 = ?
Which is a correct SQL statement but without grouping you will not get the result that you're expecting.
Another way is to use accessor and two separate relationships
<?php
//...
public function friends1() {
return $this->belongsToMany(User::class, 'users_friends', 'uid1');
}
public function friends2() {
return $this->belongsToMany(User::class, 'users_friends', 'uid2');
}
public function getFriendsAttribute() {
return $this->friends1->merge($this->friends2);
}
//...
But this way you get two separate trips to DB.

Laravel count Eloquent belongsToMany related model

I'm new to Laravel, and I got stuck with the following issue:
I have a table for the users, and groups, and a table for connecting them. The general task any user can join any group.
----------------------------------------------
| users | groups | user_groups |
|--------------------------------------------|
| id - int pk | id - pk | id - pk |
| name text | name | user_id - fk |
| email | | group_id - fk |
| phone | | any_attr |
----------------------------------------------
I have the following models:
class User
{
...
public function groups()
{
return $this->belongsToMany(Group::class, 'user_groups')->withPivot(['is_notification_requested']);
}
...
}
class Group
{
...
public function users()
{
return $this->belongsToMany(User::class, 'user_groups');
}
...
}
How do I get all of the groups, with a count of the members? I need the Group model, and a count of the users in the group.
If you're using Laravel 5.3, you can simply add withCount('relationship') as documented here: https://laravel.com/docs/5.3/eloquent-relationships#counting-related-models
Here's an example following your code:
$groups = Group::withCount('users')->get();
Now you can do this:
foreach($groups as $group) {
echo $group->user_count
}

Categories