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();
Related
I want to have multiple User classes based on the role that the User has inside our system. For example, I would like to have a User\Standard class and a User\SystemAdmin class. Then I can put logic specific to the user type in the class.
I'm hoping that I can do:
$users = User::get()
and
$user = User::find($id)
and have it load the correct classes. So get get() call would return a Collection of User\Standards and User\SystemAdmins but I'm struggling with how this can be accomplished.
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
}
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();
I've created a BaseModel class, which extends from Model. It seemed like everything was working fine, but now I've run into a problem when saving. I'm overriding the save() method in this BaseModel. I'd just like to add some attributes to the model before saving. So I do that, then call return parent::save($options);. The method signature is still the same: public function save(array $options = []).
It appears to be grabbing the name of the BaseModel class for the table name when performing the insert (it's using base_models as the table name), rather than the actual model that is being saved. Has anyone run into this before? What is the proper way of extending from the model class?
I originally created some traits to handle some extra functionality, but thought it would be a better idea to just create a base model and have my models extend from that instead.
In your model (the child one that extends the base model) add the table name explictly for example:
class SomeChildModel extends BaseModel {
// Manually set the table name
protected $table = 'table_name';
}
I realized that I previously had a static method that was creating an instance of itself using new self() and would set a few attributes, back when I was using the methods from a trait. It was fine before, but now since I moved the methods into the base model, that method was actually being called on the base model itself rather than the class that had the trait.
I was basically using the static method to instantiate the class, as I've read it's one way to avoid cluttering the constructor. But I just opted to do it in the constructor this time around since it made sense, so that was my solution.
Laravel will use snake case of the class name by default (the class where save method is called), if no $table instance variable is set. In your case it will use snake case of the BaseModel as a table name. You have two solutions:
Solution 1:
In classes which extends BaseModel add the $table instance variable as follow:
class User extends BaseModel {
protected $table = 'table_name'; // Your table name in the database;
}
Solution 2:
You can use Laravel Eloquent's Events, which allows you to hook into various points in the model's lifecycle.
You can hook into the save method as follow and make your changes. You can use these methods in your BaseClass, in traits, etc. For example in your BaseModel:
class BaseModel extends Model
{
/**
* Listen for save event
*/
protected static function boot()
{
parent::boot();
static::saving(function($model)
{
if ( ! $model->isValid()) {
return false;
}
});
}
}
The above will always call isValid before a model is saved into the storage. In this case it will return false and will not save the object.
For more info see the official docs here. Let me know if it isn't clear.
I'm developing a package that is using the user model in the main app.
I need to add a relationship to the user model that links to one of my packages models.
How can I do this?
Create a new model in my package called user and namespace it and define the relationship here?
Is there a better way?
I do not wish for who ever uses the package to go in and add the relationship themselves to the user model.
You should create a trait for that, and ask you package's users to add it in:
namespace MyAwesome\Package;
trait PerishableTrait {
public function perishables()
{
return $this->hasMany('MyAwesome\Package\Perishable');
}
}
Then tell your users to just add this single line to their User model:
class User extends ... {
use MyAwesome\Package\PerishableTrait;
}