0

I'm using the gem acts_as_commentable_with_threading, and I'd like to add something to the destroy method. Currently, if you delete a comment and it has replies it will delete the comment and it's replies. I'd like to keep this function only for the root comment, but not for the children. So if it is like this

     Comment 1
     /        \ 
     \      Comment 4
    Comment 2
       \
        \
      Comment 3

Where comment 2, 3, and 4 are all children of 1, but 3 is also a child of 2. I want to make it so that if you delete comment 2, comment 3 will still be there. However, keep it so that if Comment 1 is deleted then all of the comments under it are deleted because comment 1 is the root comment. So I have to edit the destroy method in the gem to allow this. How would I go about doing this? (Not really asking how to do the logic rather where can I edit the method, but I'd also appreciate help on the logic)

Jill
  • 533
  • 7
  • 22
  • Fork `https://github.com/elight/acts_as_commentable_with_threading`, put your own repo in the Gemfile. Alternately, monkey-patch it in your code (but I wouldn't recommend this, as it could break with the next version). – Amadan Aug 25 '15 at 04:08

1 Answers1

1

You can do this via monkey patching, which basically involves defining additional aspects of a class or module within another file. A good place to put this, I've found, is in config/initializers.

So, if you want to overwrite the destroy method of class A::B, you would make a file that says something like:

require 'loads_a_b'
module A
  class B
    def destroy_with_child_preservation
      # your code
    end
    alias_method_chain :destroy, :child_preservation
  end
end

And you can refer to the original method by calling destroy_without_child_preservation

geej
  • 26
  • 4
  • A couple questions. Confused on what A and B would be. And so if I want to use my own destroy method I would redirect it to destroy_with_child_preservation? – Jill Aug 25 '15 at 04:28
  • Actually alias_method_chain will do that for you. All you have to do is call destroy, and destroy_with_child_preservation will be invoked. A and B are arbitrary. I'm not totally familiar with the gem in question, but A might be ActiveRecord and B might be Base, having only taken a cursory look at the repo. But if that's the case, it may be better to override acts_as_commentable to add an appropriate before_destroy to do the desired functionality. Overriding destroy in ActiveRecord is probably a bad idea :) – geej Aug 25 '15 at 04:31
  • So the original destroy method of the gem will run after my version of destroy is run? If that's the case, I'm not sure that will work because in my version it will keep the replies there, but in the gem's version it will still delete it. – Jill Aug 25 '15 at 04:36
  • That will only be true if you invoke it by calling destroy_without_child_preservation somewhere. Otherwise the original code won't be executed. – geej Aug 25 '15 at 04:40
  • Here is a good explanation of alias_method_chain http://stackoverflow.com/questions/3695839/ruby-on-rails-alias-method-chain-what-exactly-does-it-do – geej Aug 25 '15 at 04:41
  • Ah makes more sense thanks. There are several modules and classes in the github. I can't seem to find out which would be correct for the module and class names. – Jill Aug 25 '15 at 04:48