Diffrence between find and where when fire update event in laravel - php

When i tried to use Eloquent event (update) it works fine to me , but i noticed that event doesn't fired when i wrote this query
Samples::where('id', $id)->update($inputs);
but it works when i wrote this
Samples::find($id)->update($inputs);
and this is my update event
public static function boot()
{
static::updating(function ($model) {
dd('it works !');
parent::boot();
}

Your first code will directly generate an UPDATE query and send it to the database. It will never load any model.
The second code will first execute a SELECT query to fill a model and then it will do an UPDATE query using the received data.
This is why the first query will never fire your update event.

Related

Model Observer Not updating if i'm getting Data From FormRequest

i'm using UserObserver and it's working only if i updated My in this way
User::find(1)->update(['name'=> 'vich']);
but when i try to do
public function update_user_profile(UpdateProfileRequest $request)
{
$user = User::find(1)->update($request->validated());
}
then the observer will not fire update event but the tow ways are updating without any errors
My Observer
public function updating(User $user)
{
dd('99');
}
I think the updated values are not 'dirty' meaning they have the same value as in the database and thus not firing any query. Not sure though, but you can try using different values will it fire then?

Laravel: How to fire event when a particular column in users table changes?

In my users table I have a column with the name verified and data type boolean with default value 'false', However, I want to fire an event when that column value to any particular user changes to 'true', So i can make a notification based on that event?
Any ideas how I can achieve this?
You could add a hook to the model event and perform a check. The code below goes in your model. You may or may not want to pass the user object with the event. This might come in handy if you're sending notifications.
public static function boot()
{
parent::boot();
static::updated(function($user) {
if ($user->verified == true) {
event(new UserVerified($user));
}
});
}
What I am thinking of is to create a trigger on update of your target table. Upon update, you can insert a record into another table EVENT.
Your code can be periodically polling from that the EVENT table to process these updates.
If you are using Oracle DB, Oracle queues will be very useful.
You could use the Attribute Events package to fire events when a model attribute changes: https://github.com/jpkleemans/attribute-events
class User extends Model
{
protected $dispatchesEvents = [
'verified:true' => UserVerified::class,
];
}

Laravel's Model observer class is not working when updating using query builder

I am explaining my issue with an example.
My model class is User and observer class is UserObserver.
I have added some code in the updated method of UserObserver that will run everytime the User model update function is used. For example updated method in theUserObserver(below) should get called whenever an update happen in User record.
class UserObserver{
function updated($userModel)
{
//Send mail code
}
}
The code in the UserObserver works when User data update like shown below:
User::find(2)->update(['name'=>'Update Name']);
However, the code in the UserObserver won't run when User data is updated in the following way:
User::where('id', 2)->update(['name'=>'Update Name']);
When I debug I can understand that User::find(2) return User model object and User::where('id', 2) will return a Builder object. So, how can I make use of our observer class method regardless of whether it is updated using User Model object or Builder object?
The issue is, I do have an existing application, some of the models are updating like User::where('id', 2)->update(['name'=>'Update Name']);. It is a difficult task to modify update statement to User::find(2)->update(['name'=>'Update Name']);.
Try as below:
User::where('id', 2)->first()->update(['name'=>'Update Name']);
The one problem with this code is that if you don't have the user with the id = 2 in your database then you will get null and you will get and exception may be as calling update on undefined entity.
So you can avoid this as below:
$user = User::where('id', 2)->first();
if(!empty($user)) {
$user->getModel()->update(['name'=>'Update Name']);
}
Dear Observer not depend on Model object or Builder Object.
It works on both statements...
User::find(2)
and
User::where('id', 2)
I am facing the same problem yesterday, but i install last Monday revisionable package and when i explore that package, its work on my code "User::where('id', 2)".
Actually i am placing my code in updating() method, but when i place the same code in saving() method its work for me...
User model class should have a fillable variable.
class User extends Model
{
protected $fillable = ['name'];
}
Try to add the first() method after where clause.
User::where('id', 2)->first()->update(['name'=>'Update Name']);
Or twist where clause to get User model object.
$user = User::where('id', 2)->first();
if(!$user) {
$user->update(['name'=>'Update Name']);
}

Laravel 5.1 Event deleting and delete not fire

I Works with Laravel 5.1 and works with events creating, updating, deleting. creating and updating works fine, but deleting method not fire. I have tests in Model, creating an Observer class and put into EventServiceProvider without any solution.
My code:
public static function boot()
{
parent::boot();
static::deleting(function($user)
{
if(count($user->getImages()) >0){
return false;
}else{
return true;
}
});
}
My code delete:
User::where('id','=',$id)->delete();
Any suggestion? Thank for all in advance
Try to use User::where('id','=',$id)->first()->delete(); It must be work, I have the same bug in my project.
For multiple rows:
User::where('id', $id)->get()->each(function($row){
$row->delete();
});
the next option if you shoot the events deleted, deleting
User::destroy(id);
or
User::destroy([id1, id2, id3]);

Laravel force delete event on relations

I'm developing a Laravel web app using Laravel 5.2. My question is very simple... How do I listen to a forceDelete event in order to forceDelete model relations?
I've been looking around the web and S.O. for a few but all the questions/answers I've found where releted to the delete method, and also in the API documentation I haven't found very much...
In my case I have a Registry model and a RegistryDetail model
Registry table
|id|name|surname|....
RegistryDetail table
|id|id_registry|....
I've created for both this boot function:
protected static function boot()
{
parent::boot();
static::deleted(function($registry) {
// Delete registry_detail
$registry->registryDetail->delete();
});
static::restored(function($registry) {
// Restore registry_detail
$registry->registrydetail()->withTrashed()->restore();
});
}
Since both models have SoftDeletes the static::deleted function is called only when the delete() method is called. if I call a forceDelete() method the related model won't be deleted from the database.
If you need more informations let me know.
Thanks in advance
The deleted event should still fire when calling forceDelete(). Inside the deleted() event method, you can check the the forceDeleting protected property via isForceDeleting() to see if you're in a regular delete or a forced delete.
static::deleted(function($registry) {
// Delete registry_detail
if ($registry->isForceDeleting()) {
$registry->registryDetail->forceDelete();
} else {
$registry->registryDetail->delete();
}
});

Categories