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 (
> [email protected] <javascript:>) 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 [email protected] <javascript:>.
> To post to this group, send email to [email protected]
> <javascript:>.
> Visit this group at https://groups.google.com/group/rubyonrails-core.
> For more options, visit 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 [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/rubyonrails-core.
For more options, visit https://groups.google.com/d/optout.