This is a somewhat trivial request, and I'm curious how many others might be interested in it, whether it's a worthy addition, etc...
I've got a couple apps that use custom flash keys for various types of messages. Along with the default :notice and :alert keys, we also use :success and :error keys. :success is used for things like successful form submissions (such as logging in). :notice is used to display useful messages and info that are not considered warnings or errors. :alert is essentially a warning, and :error messages are (surprise!) used for form errors and other failures. Each type of message might be displayed differently depending on the situation (generally this just means colors/styles, and in some specific cases we render the messages in different areas on the page).
It would be great to be able to configure the flash keys used for success and failure messages in Devise (:notice and :alert by default), ideally without having to override a ton of stuff unnecessarily - i.e. without overriding the entire SessionsController.
I'm thinking a config option (with :notice and :alert as the defaults of course) that allows you to override the two flash keys used would be fantastic.
I'd be happy to take a crack at adding the config options, utilizing the variables in place of the current keys, and writing tests for everything... Just wanted to try to gauge interest first, and mostly make sure no one was opposed to the idea!
Thanks for pinging us! However, this would make the code more complex and given Rails already picked up notice and alert as convention, I don't think the trade-offs are worthy in this case.
One way you could work around this in your app is to override DeviseController#set_flash_message to change the keys used. I have not tested this strategy but it would be my first attempt at fixing it in my own app if I were in your situation.
That's an excellent suggestion! I completely missed that somehow, and I'll give it a shot.
My other thought, if that doesn't pan out (just in case anyone with a similar situation ever stumbles on this again), was that we might rework the internal keys used for our flash messages so that instead of :success, :notice, :alert and :error we use :notice and :alert per the Rails convention and add 2 new keys:
:notice == "success"
:info == "info, messaging that's NOT an error/warning"
:warn == "warning"
:alert == "error"
Thanks for the feedback!
Just in case anyone is ever interested, here's what I ended up with in a config initializer. There were a couple spots in Devise::FailureApp that also referenced flash directly in addition to the DeviseController#set_flash_message method.
I suppose in this particular case there's no real reason to alias the methods rather than just overriding them, and it could probably be broken out into mixins if you really wanted to.
Anyway, hopefully it's helpful if anyone else ever wants to adjust this in one of their own apps! Thanks again for the suggestions.
FooApp::Application.configure do
config.after_initialize do
DeviseController.class_eval do
def set_flash_message_with_custom_keys(key, kind, options={})
case key
when :notice
key = :success
when :alert
key = :error
end
options[:scope] = "devise.#{controller_name}"
options[:default] = Array(options[:default]).unshift(kind.to_sym)
options[:resource_name] = resource_name
options = devise_i18n_options(options) if respond_to?(:devise_i18n_options, true)
message = I18n.t("#{options[:resource_name]}.#{kind}", options)
flash[key] = message if message.present?
end
alias_method_chain :set_flash_message, :custom_keys
end
Devise::FailureApp.class_eval do
def recall_with_custom_flash_keys
env["PATH_INFO"] = attempted_path
flash.now[:error] = i18n_message(:invalid)
self.response = recall_app(warden_options[:recall]).call(env)
end
alias_method_chain :recall, :custom_flash_keys
def redirect_with_custom_flash_keys
store_location!
if flash[:timedout] && flash[:error]
flash.keep(:timedout)
flash.keep(:error)
else
flash[:error] = i18n_message
end
redirect_to redirect_url
end
alias_method_chain :redirect, :custom_flash_keys
end
end
end
@markrebec Thanks we were also wondering why Devise shows alert messages instead of error messages on failed login attempts.
Most helpful comment
Just in case anyone is ever interested, here's what I ended up with in a config initializer. There were a couple spots in
Devise::FailureAppthat also referencedflashdirectly in addition to theDeviseController#set_flash_messagemethod.I suppose in this particular case there's no real reason to alias the methods rather than just overriding them, and it could probably be broken out into mixins if you really wanted to.
Anyway, hopefully it's helpful if anyone else ever wants to adjust this in one of their own apps! Thanks again for the suggestions.