Add new column model_has_permission table - laravel

I am using the Spatie laravel-permission package, and I need to modify the model_has_permission table to add a new column, "category_id," where I can store the category for each permission. Now when I want to add a new permission to a user (model), it works fine, but of course, the new column category_id leaves empty. I saw that the model_has_permissions is updated by a sync() function using the permissions(): MorphToMany function.
How can I update the permissions() function to update the category_id column? Now it only updates the default columns.

You have 2 options here:
Using the Permission relation as a classic morphToMany Relationship
Extending the Spatie Permission model
In option 1 you can use the Permission relationship as a normal morphToMany relation so all the methods are available (doc) :
(new User())->permissions()->attach($permissionIds, ['category_id'=>1]);
(new User())->permissions()->sync($permissionIds, ['category_id'=>1]);
Option 2, extending the Permission model by adding only properties/methods that you need as stated in the Spatie doc
use Spatie\Permission\Models\Permission;
class customPermission extends Permission
{
// You might set a public property like guard_name or connection, or override other Eloquent Model methods/properties
}

Related

Laravel Query Builder vs Laravel Eloquent ORM in many to many relation

Hi i want to get same result in join query builder as we get in many to many eloquent orm..
$users = DB::table('users')->join('role_user','users.id','=','role_user.user_id')
->join('roles','roles.id','=','role_user.role_id')
->get();
if I use this then I got separate array for same user with role.. for example XYZ user has 3 role then it give me 3 array of same user.
but I want to get it like this user has 3 roles like eloquent
you can use laravel relationship in view file for that you need to define relationship in user model
public function userRoles(){
$this->hasMany(UserRole::class);
}
in controller you need to use With that eager load userRole
To get user roles in view file
$user->userRole
// this will return array of user role related to that user

Can we use an observer on the attach method in Laravel?

I would like to observe a pivot table in which, rows are created with an attach method in a specific model, is there a way to Observe that pivot table through the attach method that is responsible for creating rows?
after struggling some time, I came to answer my question,
so in order to observe a table whose rows are created by the attach method, we will need to do 3 things
1- we will need to create a model that extends
$Illuminate\Database\Eloquent\Relations\Pivot
2- Connect the model to the database table with this line:
protected $table = 'data_base_table_name';
3- use the method 'using' at the end of the BelongsToMany relationship in each model that is related to the pivot table
Example:
let's say we have a model called Student and another one called Group, we have also a pivot table called group_students that is filled with the attach method since we have a student BelongsToMany groups and Group BelongsToMany Students,
we will need to create a model named GroupStudent that extends
Illuminate\Database\Eloquent\Relations\Pivot
and link it to the group_students by adding the following line in the GroupStudent Class:
protected $table = 'group_student'
After that, we will need to add the using method The BelongsToMany relations in the Student Model and the Group Model like the following:
public function students()
{
return $this->BelongsToMany(Student::class)->using(GroupStudent::class);
}
and
public function groups()
{
return $this->belongsToMany(Group::class)->using(GroupStudent::class);
}
And here we go, now whenever I create a row in the group_students table through the attach method, this will be observed and the method created will be executed.

Get formatted attributes from a related table for eloquent model

I have 3 tables
1. User table[id, name, email]
2. user_roles[user_id, role_id]
3. roles[ id, permission{post:{edit:true,delete:false}} ]
user hasone user_roles
roles belongs to user_roles
userRole.role is eager loaded in user model
Is it possible to get the permission by calling some custom function in user model.
instead of user->userRole->role everytime.
like call like $user->permissions() will return json from roles tables
You can create a method in your User model like this-
public function permissions()
{
return $this->userRole->role;
}
Laravel allows you to call your relation like that. Here $this represents your User model where you created this method. So calling a relation on $this would work without any problem.
Then you can call this with your user collection like this-
$user->permissions();
If you want to use this with logged in user then you can call it like this-
auth()->user()->permissions();

using withDefault() on belongsTo results in error

public function featuredimage()
{
return $this->belongsTo(Image::class, 'featured_image_id')->withDefault();
}
this gives me: Call to undefined relationship [featuredimage] on model [App\Models\Core\Blog\Post].
any ideas why?
it should work according to docs:
https://laravel.com/docs/5.4/eloquent-relationships#updating-belongs-to-relationships
Default Models
The belongsTo relationship allows you to define a default model that
will be returned if the given relationship is null. This pattern is
often referred to as the Null Object pattern and can help remove
conditional checks in your code. In the following example, the user
relation will return an empty App\User model if no user is attached
to the post:
public function user()
{
return $this->belongsTo('App\User')->withDefault();
}
my laravel version: 5.4.27
I have two tables:
posts table and images table
inside post table I do this:
$table->biginteger('featured_image_id')->nullable()->unsigned();
$table->foreign('featured_image_id')->references('id')->on('images')->onUpdate('cascade')->onDelete('cascade');
I had the same issue. You need to upgrade to the latest laravel version as the withDefault method is available as from 5.4.28.
To update, simply run:
composer update

firstorcreate is not working for new entry laravel

I am new to laravel and using ardent for creating models, I have below base class for all model.
class MainModel extends Ardent {
//with some common methods
}
and now i have sub model class such user
class User extends MainModel
{
//with user table and other methods related to user
}
and also I have repository for user ->User Repository and I am calling firstOrcreate method to check(user entry) and create user.
if user is exists in database then above method is working fine ,its returning existing user object but if user is not exists in database it is not creating user also its not inserting entry to table.is I am doing wrong here?
You just need to save the user after calling firstOrCreate():
$user->save();
You may want to check if the user doesn't exist before that:
if (!$user->id) $user->save();

Resources