Overriding rails #destroy argument error

邮差的信 提交于 2019-12-11 20:29:20

问题


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.


回答1:


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.



来源:https://stackoverflow.com/questions/20553576/overriding-rails-destroy-argument-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!