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.