It's an interesting idea, but my instinct says it's a huge change. We have spent 12 years learning that associated relations are mutated immediately (same behavior exists when you append to an association-- the db is touched immediately), and a change like this could be massively costly across the planet's ROR installations.
Then again, I do find the black magic of AR sometimes difficult to reckon with, especially when you save objects and their related objects also need to get saved--- how can you know which order saves & callbacks happen? (This is a HUGE problem in the Spree/Solidus codebases and has led to hundreds of thousands of hours of wasted productivity due to the black magic of AR) So, while I support all of this being cleaned up and better documented, I think it's kind of like a Rails 6 thing in my mind since it seems like a huge change. -Jason > On Jul 7, 2016, at 4:32 PM, Jeremy Mickelson <jeremy.mickel...@gmail.com> > wrote: > > Any thoughts on this proposal? > > On Thursday, February 18, 2016 at 11:26:18 AM UTC-8, Jeremy Mickelson wrote: > I agree complete that `delete` and `destroy` should remove objects from the > database immediately. The situation that I'm talking about is not really > related to the deletion of individual objects, its about how associations > behave. > > If I have a model with a has many, and I alter the array that represents that > association, it's not clear that some of those changes are in memory and some > are immediately persisted to the database. I would expect the parent model > to keep internal state representing either the objects to delete on save or a > copy of the original array so it can diff at save time and detect the > changes. > > For example: > > ``` ruby > f = Filter.first > f.destroy # happens immediately > > c = CommuncationSetting.first > the_filters = c.filters # contains 3 items > new_filters = the_filters.select { |f| /* only keep 2 of them */ } > c.filters = new_filters # right now active record deletes the remove filter > immediately > c.save! # I propose that it should wait to delete the removed filter until > here > ``` > > > On Thursday, February 18, 2016 at 12:16:08 PM UTC-7, Geoff Harcourt wrote: > One way you could handle this would be to add a virtual attribute to your > model with `attr_accessor` called `marked_for_deletion`. You could then use > that flag as a temporary change to your model without deleting it, and then > delete those objects in the final DB transaction after the user approves the > proposed changes. An advantage of this approach is that if your user abandons > their approval that none of your changes have been persisted to the database > (the virtual attribute is lost as soon as the model is no longer being > referenced). > > Another approach you could use would be the “soft delete”, where deleted > models aren’t removed from the database, but are rather marked with a flag or > a deleted_at timestamp. If you adopted that strategy, you would avoid having > the records disappear from your database, and you could unwind the action > fairly easily. > > In a non-soft delete scenario, I think calling `#delete` or `#destroy` on a > model and not having it be deleted immediately would be unexpected behavior. > > On February 18, 2016 at 2:01:55 PM, Jeremy Mickelson (jeremy.m...@gmail.com > <>) wrote: > >> In our specific project we have an object called >> CommunicationSetting that defines an automated email that a client is >> setting up. That setting has many different child objects, >> Filters for example, which would exclude or include people from the >> recipient list. In this example we would like the client to be able to test >> how changes to their filters will affect the recipient list. So we would >> like to take their proposed changes (which might include additions, >> modification, and deletions), modify the objects in memory, get the list and >> return it to the UI so the user can review it. If the user likes the >> changes, they can hit save to persist the object to the database, or if they >> don’t like it the can abandon their changes and leave the objects in the >> database as it. >> >> If deletions could be deferred until save time, than running these types of >> experiments become very trivial. The transaction workaround is plausible, >> but the whole point of having ActiveRecord objects in memory is the ability >> to modify them without persisting. Right now the behavior is inconsistent. >> Additions and modification to objects in a relation are performed in memory >> only, while deletions are immediately persisted to the database. I think >> that the inconsistency in behavior is the biggest problem. >> >> If I had something like this: >> >> c = CommunicationSetting.find(1) >> the_filters = c.filters # => [#<Filter:0x007f9abe7c3408>, >> #<Filter:0x007f9abe7b2b30>] >> >> Then I changed >> the_filters modifying one, removing one, and adding a new one, then executed >> >> c.filters = the_filters >> >> The modification and addition would be in memory only, while the deletion is >> persisted to the database immediately. This seems very inconsistent and >> counter intuitive. >> >> On Wednesday, February 17, 2016 at 2:04:32 PM UTC-7, Nicholas Firth-McCoy >> wrote: >> >> >> Could you run your code within a transaction and call the existing `destroy` >> method, and then rollback the transaction in the case that you don't want >> the deletion to persist? >> Can you share some real world examples showing why you'd need to be able to >> soft delete the associated records? There might be other, better workarounds. >> >> My guess is that this would be a complicated feature to add, but I'm not too >> familiar with the parts of ActiveRecord that this would touch. >> >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Ruby on Rails: Core" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to rubyonrails-co...@googlegroups.com <>. >> To post to this group, send email to rubyonra...@googlegroups.com <>. >> Visit this group at https://groups.google.com/group/rubyonrails-core >> <https://groups.google.com/group/rubyonrails-core>. >> For more options, visit https://groups.google.com/d/optout >> <https://groups.google.com/d/optout>. > > > -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Core" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to rubyonrails-core+unsubscr...@googlegroups.com > <mailto:rubyonrails-core+unsubscr...@googlegroups.com>. > To post to this group, send email to rubyonrails-core@googlegroups.com > <mailto:rubyonrails-core@googlegroups.com>. > Visit this group at https://groups.google.com/group/rubyonrails-core > <https://groups.google.com/group/rubyonrails-core>. > For more options, visit https://groups.google.com/d/optout > <https://groups.google.com/d/optout>. ---- Jason Fleetwood-Boldt t...@datatravels.com http://www.jasonfleetwoodboldt.com/writing If you'd like to reply by encrypted email you can find my public key on jasonfleetwoodboldt.com <http://jasonfleetwoodboldt.com/> (more about setting GPG: https://gpgtools.org) -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-core+unsubscr...@googlegroups.com. To post to this group, send email to rubyonrails-core@googlegroups.com. Visit this group at https://groups.google.com/group/rubyonrails-core. For more options, visit https://groups.google.com/d/optout.