Reputation: 6217
The following ruby code to store a previous URL is meant to exclude a certain series where the resulting action might send the user in an endless loop.
def current_user_url # store last url
if (request.fullpath != "/users/sign_in?locale=*" &&
request.fullpath != "/users/sign_up?locale=*" &&
request.fullpath != "/users/password?locale=*" &&
request.fullpath != "/users/sign_out?locale=*" &&
request.fullpath != "/users?locale=*" &&
!request.xhr?) # don't store ajax calls
session[:previous_url] = request.fullpath
end
end
when handling self-referential actions
def after_sign_in_path_for(resource)
session[:previous_url] || session[:confirm_url]
end
The wildcard character is not working as desired, as the session variable is storing, for example, /users/sign_in?locale=en
notwithstanding the use of the wildcard. note: without the use of ?locale=en
the function does work as expected.
How can this code become locale agnostic?
Update with note on solution
In case anyone drops by and is flustered by the second apporach of a wiki for the devise gem, you're not alone. I wasn't too thrilled instinctively with an after filter. Digging into Devise's store location method is an option, though not as straightforward as Max's solution below.
That does need a slight tweak though (and [ahem, yes] the question did not mention devise) where routes need to invoke devise_for
and the controller needs to inherit from devise
devise_for :users, :controllers => { registrations: 'registrations', sessions: 'sessions' }
class SessionsController < Devise::SessionsController
skip_before_action :store_location
end
This feels cleaner to me come maintenance time...
Upvotes: 0
Views: 696
Reputation: 102250
Instead of request.full_path
you can use request.path
which does not include the query string.
But a better solution altogether is just skipping the callback on the effected controllers / actions as this distributes the responsibilities correctly.
class ApplicationController < ActionController::Base
before_action :store_location
def store_location
session[:previous_url] = request.fullpath
end
end
class SessionsController < ApplicationController
skip_before_action :store_location
end
class UsersController < ApplicationController
skip_before_action :store_location, only: :index
end
Upvotes: 1
Reputation: 239501
Wildcards don't work in string comparisons, which are just straight character-by-character equality checks.
You need to use a regular expression, and check for a match
, or use String#[]
:
if (!request.fullpath[%r{\A/users/sign_in\?locale=.*\z}] &&
...
Upvotes: 0