1

Hay! The system I'm working on has the following feature: after your disconnect, the next time you log in, you'll be redirected to the last page you've been.

That info is stored in the DB, as a string called first_place_after_login, and Rails will take the user there.

The problem is that sometimes that route does not exist anymore.

Imagine your last page was 'activity/1', and that activity got deleted, when you log in, you're gonna see an error screen. The main issue with this, is that some users get confused why they hop right into an error when they just entered a 'normal' route (but got redirected to a invalid one).

So, before redirecting my user, I need to make sure that that route still exists, and it would be very bad to create a specific DB check for that (because there are dozens of possible routes that could not exist). So I wanted a way to send a request to my own route, and check the status it returns me.

I've tried this: Check if URL exists in Ruby, but the system is login-secured, so request returns as without permission.

Is there any practical way for me to validate my own routes?

CH4B
  • 734
  • 1
  • 9
  • 27
  • I am afraid that you will not be able to implement this without database checks. There are two reasons why `/activity/1` might be invalid. 1) the `ActivitiesController` or its route was removed which is unlikely and easy to detect. And 2) there is no activity with the id `1` and the only way to discover this is to look into the database. – spickermann Aug 19 '19 at 18:52
  • It's not about checking DB or not, I just wanted a way to validate ANY route ;/ – CH4B Aug 19 '19 at 18:55
  • @spickermann Like "if tryRoute(activity/') == false redirect_to(dashboard)" – CH4B Aug 19 '19 at 18:56

3 Answers3

0

How about

1) adding an extra field status in the table and set as 'false' for page which gets deleted.

2) Redirect to the URL only for page which has active status or redirect it to a fallback URL.

shivashankar
  • 1,147
  • 1
  • 10
  • 16
  • Either way I'd have to check on that specific value in the DB... Like this, too many things will changes (there are really many pages where this can happen), I wanted a solution that would solve every one of them, like a try-catch – CH4B Aug 19 '19 at 18:07
  • 1. Is it possible to save the last visit page in cookie? 2. In routes.rb you can try `get '*path', to: 'catch_all#index'` May be it gives you some hint – shivashankar Aug 19 '19 at 18:14
  • @CH4B You will *always* have to check against the DB, because it's the values in the DB that determine whether or not the entity being looked up exists. The only thing you need to know is whether or not they're hitting that page from a last-URL or if they navigated there themselves. – Dave Newton Aug 19 '19 at 18:29
  • unfortunately the cookie is not possible :( thats because, if I were to open the system back at home, it should still take me to the last page I saw. – CH4B Aug 19 '19 at 18:30
0

If you need to make it only in case of a user who logs back in via SessionsController here's my suggestion:

You could create some kind of before_action e.g. ensure_first_place_after_login_exists in your SessionsController and rescue from specific errors with redirection to root_path or any other place.

Tomasz S
  • 183
  • 5
0

You can use the same method that Rails uses to determine the controller and the other params from the route:

Imagine /activities/1 exists:

Rails.application.routes.recognize_path('/activities/1', method: :get)
#=> {:controller=>"activites", :action=>"show", :id=>"1"}

And if that routes doesn't exist anymore:

Rails.application.routes.recognize_path('/activities/1', method: :get)
#=> raises ActionController::RoutingError (No route matches "/activities/12")

With this you can build a helper method like:

def redirect_to_last_page(url_from_session)
  Rails.application.routes.recognize_path(url_from_session, method: :get)
  redirect_to(url_from_session)
rescue ActionController::RoutingError
  redirect_to root_path
end

Keep in mind that it doesn't cover cases like that the URL itself is valid like /activities/1 but the activities with the ID 1 was deleted from the database.

spickermann
  • 100,941
  • 9
  • 101
  • 131