what do you get when you
dd(auth()->user()->current_team)
I have a model Order that stores orders, and has a foreign key team_id that identifies a specific order for a particular team. I used boot() method in a trait to store the team_id automatically:
trait FilterByTeam
{
protected static function boot()
{
parent::boot();
self::creating(
fn ($model) => $model->team_id = auth()->user()->current_team
);
}
}
Every other model works fine, and the data is stored. With this Order model, I get a QueryException from Eloquent: SQLSTATE[HY000]: General error: 1364 Field 'team_id' doesn't have a default value. I don't know what I'm doing wrong. In my $fillable[], I have team_id as fillable.
what do you get when you
dd(auth()->user()->current_team)
@anilkumarthakur60 I get the id of the current_team, which is an integer 1
protected static function boot()
{
parent::boot();
self::creating(function ($model) {
$model->team_id = auth()->user()->current_team;
});
}
this should probably work .....
Can you show one model that works and one that does not?
@Sinnbeck In the create(), Laravel Ignition highlights this line in the create() method:
Order::create([
$request->validated(),
'customer_id' => $request->customer_id,
'order_date' => $request->order_date ?? date('Y-m-d'),
'service_id' => $request->service_id,
'discount' => $request->discount ?? 0,
'user_id' => auth()->id(),
'quantity' => $request->quantity,
'balance' => ceil($total - ($total * $request->discount)),
'updated_by' => auth()->id(), //* <---- this line
]);
@Sinnbeck This is the code that works:
Customer::create($request->validated());
@Emokores yeah that makes sense as that is where the error originates. I have never set a parameter like that in a hook, but if you say it works on other models, I assume it has to do with the model.
@Emokores and Customer has team_id column as well that isn't nullable?
@Sinnbeck It was working before until I added the team management functionality into the project.
@Sinnbeck This is what I don't understand.
@Emokores so that team_id isn't actually working for other models?
Order::create([
...$request->validated(),
'customer_id' => $request->customer_id,
'order_date' => $request->order_date ?? date('Y-m-d'),
'service_id' => $request->service_id,
'discount' => $request->discount ?? 0,
'user_id' => auth()->id(),
'quantity' => $request->quantity,
'balance' => ceil($total - ($total * $request->discount)),
'updated_by' => auth()->id(),
'team_id' => auth()->user()->current_team
]);
@Sinnbeck But I can't understand why the trait is not working for this particular model?
@Sinnbeck But I have another boot() method in the Order model that generates order numbers (alpha-numeric). Could it be affecting the trait?
public static function boot()
{
parent::boot(); //* runs the autogenerated stub
//* autogenerated stub
self::creating(function ($model) {
$model->number = $model->whereMonth('order_date', Carbon::now()->month)->max('number') + 1;
$model->order_no = 'H5M-O' . date('ym') . str_pad($model->number, 5, '0', STR_PAD_LEFT);
});
}
@Emokores yeah that overwrites it. You need to import the method from the trait and run it.
Might just be easier to add it manually here (at least for testing)
@Sinnbeck Yeah I thought the same thing. I copied and pasted the code in the boot() method of the trait into that of the model and everything works fine.
Just a question: Can you merge two boot() methods in Laravel?
@Emokores you can import a method from a trait with another name and run it. But not sure how it will work as you are hooking into creating twice then
@Sinnbeck Oh, I see! Then using the boot() method of the model is the best solution, and putting all the logic you want there. So now, that model no longer uses the trait, but its boot() method.
@Emokores something like this btw
use FilterByTeam {
boot as teamBoot;
}
And
public static function boot()
{
parent::boot(); //* runs the autogenerated stub
self::teamBoot();
@Sinnbeck Wow! This is new! I've just tried this but I have a problem with my editor. It changes the public static function boot() { .. } of the model to public function boot(){ ... } and that gives me an error from Eloquent. I'm using VS Code with Intelephense extension
@Sinnbeck But when I edit the file outside of my editor, everything still works as fine.
use FilterByTeam {
boot as teamBoot;
}
public static function boot()
{
parent::boot(); //* runs the autogenerated stub
// ... <--- boot logic for the model
self::teamBoot(); //* boot logic from the trait
}
@Emokores you might need to change it slightly as it's a static function. I wrote it from memory and I am unsure of static methods. Perhaps
use FilterByTeam {
boot as public static teamBoot;
}
@Sinnbeck I get a syntax error with that!
@Emokores sorry will take some research to find out how to do it. I cannot currently find anything sadly
@Sinnbeck Actually, your first answer was correct. I think Laravel is opinionated about the naming of the boot() method. I think you have to name it with bootTheAction()
use FilterByTeam {
boot as bootTeamIdentifier;
}
I changed it to this and my editor stopped formatting my static method wrongly, bringing the error.
slightly change your Order::create() method
Order::create(
$request->validated()+[
'customer_id' => $request->customer_id,
'order_date' => $request->order_date ?? date('Y-m-d'),
'service_id' => $request->service_id,
'discount' => $request->discount ?? 0,
'user_id' => auth()->id(),
'quantity' => $request->quantity,
'balance' => ceil($total - ($total * $request->discount)),
'updated_by' => auth()->id(), //* <---- this line
]);
@anilkumarthakur60 I still get the same error
@Emokores check your fillable properties ...it might be missing there ..
@anilkumarthakur60 I have team_id in my $fillable[] array. But I have another boot() method in my Order model that autogenerates order numbers (alpha-numeric). Could it be affecting the trait?
public static function boot()
{
parent::boot(); //* runs the autogenerated stub
//* autogenerated stub
self::creating(function ($model) {
$model->number = $model->whereMonth('order_date', Carbon::now()->month)->max('number') + 1;
$model->order_no = 'H5M-O' . date('ym') . str_pad($model->number, 5, '0', STR_PAD_LEFT);
});
}
Please or to participate in this conversation.