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.

Reply via email to