I have a products table that has an serial id, a sku, an is_current flag, and then various attributes about the item. It also has a unique index on sku where is_current = true to prevent having more than one current record.
What I want to happen is, when you change the model and call save(), a new record is created instead and the existing record is only changed to flip the is_current flag. So what I think I want is a way to copy the model with replicate(), discard the changes in the old model and just update to flip the current flag false, and then insert the new model. Something like that, although I might not have thought that though 100%. Can this be done in as a part of an “updating” event? Is a trigger a better choice to prevent accidents if some direct table updates occur?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
You can do this 2 ways, One is hooking into the save event on the model. The other is creating a new method on the model, I would probably go the new method route. like $product->updateCurrent();
which would then do all of the logic.
public function updateCurrent($details) { $newProduct = $this->replicate()->fill($details); $this->update([ 'is_current' => false, ]); return $newProduct; }
Otherwise the saving event
product model
protected $dispatchesEvents = [ 'saving' => AppEventsProductSaving::class, ];
ProductSaving event
<?php namespace AppEvents; use AppProduct; use IlluminateQueueSerializesModels; class ProductSaving { use SerializesModels; public $product; /** * Create a new event instance. * * @param AppProduct $product */ public function __construct(Product $product) { $this->product = $product; } }
Now you need a listener
ProductSaving
<?php namespace AppListeners; use AppEventsProductSaving as ProductSavingEvent; class ProductSaving { /** * Handle the event. * * @param AppEventsProductSavingEvent $event * @return mixed */ public function handle(ProductSavingEvent $event) { $product = $event->product->replicate(); $old_product = Product::find($event->product->id); $old_product->update([ 'is_current' => false, ]); return false; // Prevent model from saving. } }
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0