Passing a block for a filter vs symbol. Why different?

The Devise::RegistrationsController has this code:

class Devise::RegistrationsController < DeviseController
  prepend_before_filter :require_no_authentication, :only => [ :new, :create, :cancel ]
  prepend_before_filter :authenticate_scope!, :only => [:edit, :update, :destroy]

I’m subclassing this controller, and I ran into a subtle difference in the way that I call prepend_before_filter:

The this does not work in the subclass

prepend_before_filter :authenticate_scope!, :only => [:update_password]

This does work

prepend_before_filter :only => [:update_password] { authenticate_scope! }

And this also works.

  prepend_before_filter :authenticate_scope!, :only => [:update_password, :edit, :update, :destroy]

It seems that if you call prepend_before_filter in a subclass, you cannot simply add to the only list.

Would this be a bug? It’s certainly not expected.

I’m guessing that the technique of passing a block is better in terms of upgrading Devise in the future.

Your first example that you say doesn’t work and your third example that you say does differ only in the number of arguments in the :only array.

Are you sure that adding other actions to that array makes it work?

Specifying all the methods names used in the superclass makes those get used with the filter in the sense that what the superclass intended is still called, rather than not called.

I suppose a subclass might want to override the filter and not have the methods called.

Basically, there should be a flag to append values to the superclass, or else there should be a method to get the the settings on the superclass, and then I can append to the array. I don’t like having to manually copy the values out of the superclass, because I don’t want to check this every time I upgrade Devise.