Laravel eloquent doesn't insert data when bug occur during multiple insert - laravel

I'm trying to insert users using csv.
My model has an observer on "created" event.
However I can have a bug after some $users->save() because of code in my function created event (which I fixed).
The code in created event send an email to the user. The problem is if code crash after 5iterations, I got my 5emails send but no user in my db.
I'm wondering if Eloquent use transaction when you call multiple times save() ?
If yes how to force Eloquent to really save my object after each end of event created ?
May be I'm misunderstanding something with event, because I don't see the point of using this event if your not sure to have your model insert in your DB.

Finally found what was wrong...
To insert csv my project use :
https://github.com/Maatwebsite/Laravel-Excel
And after some research, this is "why" eloquent use transaction in my case :
https://docs.laravel-excel.com/3.1/imports/validation.html#database-transactions

Related

Simple private messaging system. How to mark as read

I'm building an app in Laravel, and using the eloquent ORM.
i want to create a simple private messaging system within my application. Nothing mad complex. It will basicaly be like email. It has a recepient, title, content and timestamps.
I want the ability to show if it's read/unread. Would having a column as a boolean called 'read' which has a default value of 0 work. When the user clicks on it, the read attirbute changes to 1, and the message is marked as read.
How would I update the attribute, when the message is opened.
Laravelish way, is to use a column named read_at, and set it to NULL if unread, and the current timestamp when read.
Migration part of read_at may look like:
$table->timestamp('read_at')->nullable()->default(null);
Note: do not forget to add read_at to $dates array so working with read_at is easy - carbon way.
If you are not using front-end framework like Angular or react, make ajax request to your controller function. In controller function update the db table using ORM or Query Builder. Using Ajax you can do it without affecting to the user view.
if you are making simple messaging system, store a flag with read. When the user clicks on a message, take that message's id and update that records read with 1 and unread 0 using an update action.

Triggering Laravel observers on multiple records

I have been using Laravel Observers to handle my app logic whenever my models get deleted/updated/saved. I noticed in some cases these observers don't get triggered. For example if I use
Model::where(active,1)->update([some stuff]);
the observers never get triggered. It is very annoying to have to fetch all records and run a forloop on each instance and call update. Is there a way around this or are there any good practices to handle these scenarios?
When you do this:
Model::where(active,1)->update([some stuff]);
Query Builder's update() method is executed instead of Eloquent's update() method.
If you want to trigger Eloquent events, you need to update rows one by one.
Events and listeners instead? You can run the update either raw or query builder, pass those effected rows in the event.

Algolia Update Index On Relational Database change with Laravel Scout

I have implemented Aloglia for my Movies table with actors as relational table and it works fine.
Problem:
When I update any movie its also updating algolia index (its good). But how can I update index if I made any change in relational table (for example update an actor of movie).
How to push a specific record manually with laravel scout.
Thanks
The issue itself lies in laravel's events. Whats happening is scout is listening for an 'updated' event which only occurs in laravel when the model object is saved and is dirty (aka value differ from that in the db).
There are two ways you can do this.
The bad lazy way would simply be to add ->touch() to the model prior to save - this will force the updated_at field to update and ultimately trigger the updated event. This is bad as you're wasting a DB query.
The second and preferable way is to register another observer on 'saved' which triggers regardless of whether or not the object is dirty. Likely you either want to check if the model is dirty and only index when its not (to prevent double indexing from the updated event) or just de-register the 'updated' listener that comes in Scout.

Laravel audit log for model events using generic way

I am using Laravel 5.2.
I want to create audit log entries for each and every model in my project. Whenever any model gets created, updated or deleted; the audit log for that record should be logged along with old and new values.
For example if I update user's first name from John to George, the audit table entry should be logged something like First name updated from John to George.
I know I can fire created, updated and deleted events and using individual listners I can log this. But I want to create it more generic way.
I don't want to define boot method with created, updated and deleted events in each and every model as I have more than 75 models existing in my project. I don't like duplication of that method in each and every model. I want to make it more generic way, like use something like trait, using that in model should automatically identify which event is fired.
Again, the listener will also listen the event but not for any specific model but generic. I don't want any tight coupling. It should decide which model is updated and make entry of log according to that.
Can any one guide me how to achieve this?

Laravel : Delete all records that are not in array

I have a datepicker calendar in my views, and basically I need to synchronize the selected dates (that I send in ajax) with a BoxDeliveryDate model (which only has one column named "date").
So in my Controller I was able to write a pretty nice method to only create a new record if one the selected dates is not yet stored in the database, like this :
foreach (Request::get('dates') as $date) {
$date_formated = date('Y-m-d', strtotime($date));
BoxDeliveryDate::firstOrCreate(['date'=>$date_formated]);
}
Now, if the user de-select one the dates in the datepicker, later, and synchronize, I need to delete it from the database.
Is there a nice way to do that in Laravel ? In other words, to delete every record of the table that are NOT in my Request::get('dates') ?
Also, I searched for a simple way to synchronize everything with only one method, but couldn't find anything.
Thanks for helping !
You can use whereNotIn() for that:
BoxDeliveryDate::whereNotIn('date', Request::get('dates'))->delete();
Note that this will not trigger any model events nor will it work with soft delete. Also, depending on the format of dates you might have to format the array before passing it to whereNotIn().
Also I believe it should be Request::input('dates') but it's possible that both actually works...
I would highly recommend using the soft delete trait (built into Laravel) if your doing mass deletes!
http://laravel.com/docs/4.2/eloquent#soft-deleting
$this->model->whereNotIn('id', $ids)->delete();

Resources