Overriding rails #destroy argument error

activerecord, ruby-on-rails

Solution

It should be

super()

Here's the full implementation

def destroy(mode = :soft)  
  if mode == :hard  
    super()
  else  
    ... soft-delete actions ...  
  end  
end

The reason is because when you call `super` without passing any argument, Ruby will call the parent method passing the same arguments that are passed to the original method.

But because the original `destroy` method in Rails takes no argument, the result is the error

ArgumentError: wrong number of arguments (1 for 0)

because your call is translated into

if mode == :hard  
  super(mode)

Using `super()` (with empty `()`) forces Ruby to pass no arguments to the parent method.

As a side note, I normally prefer to "rename" the old object, instead of overriding it.

alias _destroy destroy

def destroy(mode = :soft)  
  if mode == :hard  
    _destroy
  else  
    ... soft-delete actions ...  
  end  
end

In this way you will still retain a reference to the original _destroy.

Even better, I prefer to expose a custom API instead of overriding Rails default methods. It helps me to expose a custom API loosely coupled to ActiveRecord internals.

Problem

My Goal: Override the #destroy method in rails so that gems like Devise will perform a soft-delete. My Attempt: ``` def destroy(mode = :soft) if mode == :hard super else ... soft-delete actions ... end end ``` When this is called on the object it get... ArgumentError: wrong number of arguments (1 for 0) I would like for this to default to soft-deleting, but have the option to fully destroy the object. My approach may not be the best way to do this, but any advice would help.

Original source