On 04/05/2012, at 2:54 PM, Ben Hoskings wrote:

> You're better off making a second set of tables, like deleted_companies and 
> deleted_staffings, inserting rows into them in a destroy callback on the main 
> models.

There's already such a table - one that resolves many-to-many association 
(staffings).
I thought about using PG array to store the IDs or another table. But I don't 
feel those are right places.

> You could use is_paranoid (which superceded acts_as_paranoid), but it's a bit 
> of a nightmare. 
Thanks. I see. Feels like much more than I really need.

> Creating extra tables doesn't violate DRY if you organise your code well, and 
> is a more correct representation of the data: deleted records are presumably 
> there for archival purposes, and don't form part of the working set, so they 
> shouldn't sit alongside active data.

The thing is that the records are no deleted ("soft deletion" is used as a 
concept here) , those are "inactive" and represent the status of the user 
within the company.
Thus the many-to-many resolving table feels like the right place for it.

I only want to preserve the existing interface where there was no such a notion 
before. (has_and_belongs_to_many => has_many through).
This is really easy with the condition:

has_many :users, through: :staffings, conditions: {staffings: {active: true}}

but unfortunately I don't know how to set "active = false" instead of deleting 
the Staffing record.

Staffing#before_destroy doesn't seem to work when clearing association 
`company.users = []`



> 
> [1] When deleting a record, it's not clear what to do with associated ones:
> 
>  - If you don't mark them as deleted too, you'd have to join the parent table 
> to exclude records with a deleted parent;
>  - If you do, then when it's time to undelete, you can't tell if the child 
> record was actually deleted or if it was just marked that way when the parent 
> was deleted.
> 
> The whole thing is a big messy concern that should be separated, table-wise.
> 
> - Ben
> 
> 
> 
> On 04/05/2012, at 2:44 PM, Dmytrii Nagirniak wrote:
> 
>> Yeah, modifying the AR methods is way too dirty.
>> 
>> The problem here is to preserve the initial interface/contract on 
>> Company#users and add Company#staffings on top of it.
>> So that:
>> 
>> company.users << user1
>> company.save!
>> company.should have(1).staffing
>> 
>> company.users = []
>> company.save!
>> company.should have(1).staffing
>> company.should have(0)users
>> 
>> I'm not sure if the before_destroy callback will do the job. Need to play a 
>> bit with.
>> 
>> Also need to play with acts_as_paranoid.
>> It seems to be non-maintained anymore.
>> Probably something from 
>> https://www.ruby-toolbox.com/categories/Active_Record_Soft_Delete
>> would be a better choice.
>> 
>> Anyway, I'll play with all that.
>> 
>> Cheers.
>> 
>> 
>> 
>> On 04/05/2012, at 2:37 PM, Pat Allan wrote:
>> 
>>> I'd be extremely wary of modifying the behaviour of ActiveRecord's own 
>>> methods. I'd recommend creating your own custom destroy method which 
>>> behaves how you want, and make sure you're using that wherever appropriate. 
>>> Hence, it's been a long time since I've used acts_as_paranoid.
>>> 
>>> Not quite sure how that would fit into an association setup, though. I'm 
>>> sure it'd be possible to code something together.
>>> 
>>> -- 
>>> Pat
>>> 
>>> On 04/05/2012, at 2:27 PM, Craig Read wrote:
>>> 
>>>> I didn't know about acts_as_paranoid.
>>>> 
>>>> I was thinking a callback on before_destroy.
>>>> 
>>>> def before_destroy
>>>> update_attribute(:active, false)
>>>> return false
>>>> end
>>>> 
>>>> On Fri, May 4, 2012 at 2:19 PM, Chris Herring 
>>>> <[email protected]> wrote:
>>>> I would just use something likes acts_as_paranoid and then then have the 
>>>> dependent destroy conditions on your associations.
>>>> On Friday, 4 May 2012 at 1:55 PM, Dmytrii Nagirniak wrote:
>>>> 
>>>>> Hi,
>>>>> 
>>>>> What is the easiest way to implement soft-deletes on has_many through 
>>>>> association?
>>>>> 
>>>>> What I want is something like this:
>>>>> 
>>>>> class Company > ActiveRecord::Base
>>>>> 
>>>>> has_many 
>>>>> :staffings
>>>>> 
>>>>> has_many 
>>>>> :users, through: :staffings, conditions: {staffings: {active: true}}
>>>>> 
>>>>> end
>>>>> 
>>>>> I want to use Company#users the following way:
>>>>> 
>>>>>   • the Company#users should be a normal association so that it works 
>>>>> with forms.
>>>>>   • when adding a new user, a new Staffing with active: true is created.
>>>>>   • when removing a user, the existing Staffing is updated active: false 
>>>>> (currently it just get deleted).
>>>>>   • when adding a previously removed user (so that Staffing#active == 
>>>>> false) the Staffing is updated to active: true.
>>>>> I thought about overriding the Company#users= method, but it really isn't 
>>>>> good enough since there are other ways of updating the associations.
>>>>> 
>>>>> What is the Rails Way of doing this sort of thing?
>>>>> 
>>>>> (I asked it at SO too - 
>>>>> http://stackoverflow.com/questions/10441633/soft-delete-on-has-many-through-association)
>>>>> 
>>>>> What I came up with so far is:
>>>>> 
>>>>> - override user= and user_ids
>>>>> - deny the use of any other association modifier methods:
>>>>> 
>>>>> But all that feels really, really dirty.
>>>>> 
>>>>> has_many :developments, through: :development_participations,
>>>>>         conditions: {development_participations: {allowed: true}} do |a|
>>>>>           %w{<< delete clear build create}.each do |association_method|
>>>>>             # Disable assoc modifier methods for now
>>>>>             # 
>>>>> http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many
>>>>>             define_method(association_method) do |*args|
>>>>>               raise 'nah, not yet supported. Use `developments=` instead.'
>>>>>             end
>>>>>           end
>>>>>         end
>>>>> 
>>>>> def users=(others)
>>>>> self.development_ids = others.collect &:id
>>>>> end
>>>>> 
>>>>> def development_ids=(other_ids)
>>>>> # All the merging magic here  
>>>>> end
>>>>> 
>>>>> 
>>>>> Any thought?
>>>>> 
>>>>> 
>>>>> Cheers,
>>>>> Dmytrii
>>>>> http://ApproachE.com
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> -- 
>>>>> You received this message because you are subscribed to the Google Groups 
>>>>> "Ruby or Rails Oceania" group.
>>>>> To post to this group, send email to [email protected].
>>>>> To unsubscribe from this group, send email to 
>>>>> [email protected].
>>>>> For more options, visit this group at 
>>>>> http://groups.google.com/group/rails-oceania?hl=en.
>>>> 
>>>> 
>>>> -- 
>>>> You received this message because you are subscribed to the Google Groups 
>>>> "Ruby or Rails Oceania" group.
>>>> To post to this group, send email to [email protected].
>>>> To unsubscribe from this group, send email to 
>>>> [email protected].
>>>> For more options, visit this group at 
>>>> http://groups.google.com/group/rails-oceania?hl=en.
>>>> 
>>>> 
>>>> 
>>>> -- 
>>>> Craig Read
>>>> 
>>>> @Catharz
>>>> https://github.com/Catharz
>>>> http://stackoverflow.com/users/158893/catharz
>>>> 
>>>> 
>>>> -- 
>>>> You received this message because you are subscribed to the Google Groups 
>>>> "Ruby or Rails Oceania" group.
>>>> To post to this group, send email to [email protected].
>>>> To unsubscribe from this group, send email to 
>>>> [email protected].
>>>> For more options, visit this group at 
>>>> http://groups.google.com/group/rails-oceania?hl=en.
>>> 
>>> 
>>> 
>>> -- 
>>> You received this message because you are subscribed to the Google Groups 
>>> "Ruby or Rails Oceania" group.
>>> To post to this group, send email to [email protected].
>>> To unsubscribe from this group, send email to 
>>> [email protected].
>>> For more options, visit this group at 
>>> http://groups.google.com/group/rails-oceania?hl=en.
>>> 
>> 
>> 
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "Ruby or Rails Oceania" group.
>> To post to this group, send email to [email protected].
>> To unsubscribe from this group, send email to 
>> [email protected].
>> For more options, visit this group at 
>> http://groups.google.com/group/rails-oceania?hl=en.
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Ruby or Rails Oceania" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to 
> [email protected].
> For more options, visit this group at 
> http://groups.google.com/group/rails-oceania?hl=en.
> 

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
or Rails Oceania" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/rails-oceania?hl=en.

Reply via email to