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.
Related
I have a Case View which shows all the records that were created by the me (My Cases view). I now want to all those Cases edited/modified by me to be visible in that view. The problem is those modified by me could be later modified by the system when a workflow updates the Case, which changes the Modified By User data. Thus, not allowing me to use Modified By (Current User) as a condition for the view.
Is there any other way or condition which I can use to make sure the I can accomplish this?
Thank you in advance.
You may create a new Entity with One to Many relationship with Case Entity. Whenever there is Insert or Update you can add a new record in the mapping entity with Modified By Information and Created On OOB.
You can create a view in the new entity with record modified by Me.
P.S - Single case record will be edited multiple times with multiple users so it will result in high volume of data and may want to look for archiving strategy.
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
I am having an issue getting related models to update with scout elastic search.
$event->priceranges()->delete();
$event->priceranges()->Create([
'price' => $ticket['ticket_price']
]);
$event->update([
'show_times' => $request->showtimes,
]);
$event->searchable();
In my database I see the event and price range tables update. However when I look at my elastic search data, only data on the event has been updated. Any related models are not updated.
If I make a second update to the model and price range model, then the elastic search data shows my data from the first update I made (it is always one update behind for related models)
I tried doing
$event->pricerange->searchable()
but gives me an error because I don't have a searchable index for pricerange, I am just using my event model and its relationship to index. Is there a way to force the update other than searchable()?
Looks like your relationship is being indexed in the Event model index, correct?
Probably it's not being updated because the relationships are already loaded, and Laravel doesn't update the relationship data that is already loaded, for example:
$event = Event::with('priceranges')->first()
var_dump($event->priceranges->count()): // outputs for example 5
$event->priceranges()->create([...]);
var_dump($event->priceranges->count()): // still outputs 5, meaning that the created pricerange is not loaded
So, to fix this issue you can reload the model before calling searchable():
$event = $event->fresh();
$event->searchable();
But, note that everytime you update, the searchable method is already being called, so you will be indexing it two times on every update.
So, alternatively you can update your toSearchableArray() method in Event model to get a fresh model before returning the data (I'm assuming that you are using the babenkoivan/scout-elasticsearch-driver).
I have created a polling system and in the backend (CMS area) I want the ability for admins to be able to remove polls. When an admin removes a poll, it should soft delete the poll. This is working as intended, however I also want to have the ability for the admin to be able to restore a poll. To do this I am displaying all of the polls (including the soft deleted polls) in the admin area.
PollController index() to get all polls
$polls = Poll::withTrashed()->get();
In the blade I want to have two different buttons for each poll. One of restoring and one for deleting but I only want to display 1 button for each poll depending on whether it can be restored or deleted.
To do this, I have put this inside the foreach in the blade:
#if($poll->trashed())
// Restore button
#else
// Delete button
#endif
However the issue is, trashed() keeps returning true for all the polls when only 1 out of the 3 polls I have are actually soft deleted. I am unsure as to why trashed() returns all of these are true?
How would I get this method working correctly? Thanks.
PART 1
It depends on your query. When using soft deletes, Laravel will query all models that are not soft-deleted by default. When you also want to get the soft-deleted models, you need to call the withTrashed() method on your query. Read more here:
https://laravel.com/docs/5.5/eloquent#querying-soft-deleted-models
To understand what withTrashed() does, you need to understand how soft-deleting works. Soft-deleting models works by adding a new column to your database tables called deleted_at. It's value defaults to null. When you soft-delete a model, Laravel will put the current timestamp into that column. Therefore, this field doesn't contain a null value anymore.
When querying models when using soft-deletes, Laravel appends a deleted_at is null condition to the query. Calling the withTrashed() method, removes that condition from the query.
Have a look on the source of the default query modifier and the withTrashed method.
PART 2
That are events. You can call that to tell Laravel, that it should execute that specific closure when this event happens. In your example, it is listening for the "deleting" event. See more on that here:
https://laravel.com/docs/5.5/eloquent#events
PART 3
You can entirely delete soft-deletable models with the forceDelete() method. See "Permanently Deleting Models" here:
https://laravel.com/docs/5.5/eloquent#querying-soft-deleted-models
FOR EXAMPLE
$items = App\Model::withTrashed()->get();
If you want to restore a single item, just find it by ID:
$item = App\Model::find($id);
I want to store changes to all fields in Eloquent model into database.
I can do it using created and updated events but there is a problem with multiple foreign relations (described as separate tables).
Example:
User
login
Roles -> hasMany
When I update login field it is easy to write old and new value into database, but when I update Roles relation nothing happens.
How can I track all foreign relations (like hasMany, hasManyThrough, ManyToMany)?
Owen-it has a very nice Library called laravel-auditing, which keeps an easy to query list of all changes that are made to a model, and I think it does quite an awesome piece of work. Have used it and it is worth it to try out.
There is no embedded and simple method to do it.
Eloquent doesn't provide any method to implement observers on related models by design. Many proposal in this way have been rejected by Taylor (just one example).
The only thing you can do, is to create your own methods to do it.
You have many possibilities, here are some of them in order of complexity (some of them are "dirty" :-)
add a created and updated observer on each related model
override the save() or create your own saveAndFire() method on your eloquent instances, and from that method retrieve the parent and call its log methods before saving. (this is a little bit "dirty" imho)
encapsulate all your persistence layer and fire events yourself on saving objects (look at the repository pattern, for example)