New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rails Router Catchall Picks Up ActiveStorage Routes #31228
Comments
This is not a problem only with Active Storage. Any engine that you include in your application that has routes will have the same problem. So I don't think there is something we can do in our side. Could you try to mount Active Storage engine in our routes like this? mount '/', to: ActiveStorage::Engine Make sure it is before your catch all route. |
@rafaelfranca Thanks for looking into this. I just tried
and
Neither one is picking up the routing before the catchall. Then I went looking at another Rails application I work on where we have a catchall route. I noticed that the engines are mounted there as well, and that even the ActionCable server needs to be mounted:
So it would seem that I just need to figure out how to get the ActiveStorage engine mounted onto the routing, so it kicks in before the catchall route. |
It looks like you're familiar with routing issues, I see you've looked into #30783 as well. I'm still poking around to understand the problem more. |
@peterc were you able to find a solution to this? |
For all those who follow, this will work in the meantime: get '*all', to: 'application#mount', constraints: lambda { |req|
req.path.exclude? 'rails/active_storage'
} It's kinda ugly and probably could be done better, but it works. |
@kieraneglin I haven't poked at it lately. For now, I'm just routing one path to work around it. I like your solution. Ugly and works is better than other options, I'll take it! 👍 |
This issue has been automatically marked as stale because it has not been commented on for at least three months. |
Can still reproduce on 5.2.0b2 |
Still looking for a better solution to this one. It got me late last night while I was testing 5.2 and ActiveStorage on an old project. Catch all routes are fairly common and the way this breaks isn't immediately obvious. Better solution and perhaps a note in the guide? |
9 out of ten of my Rails projects from the last 10 years need catch all routes for something (eg. dynamic paths for CMS-based public web content with user generated nice urls). Although the routing is a bit complicated, I would much prefer if developers were told to put the routes in the routes.rb file to allow control of route order, path naming etc. for ActiveStorage.
|
I agree with @jspang in that it would be clearer where these routes are coming from if they were explicitly defined by the programmer in routes.rb. Given that there is some level of set up for existing apps (ie. upgraded Rails apps) with bin/rails active_storage:install, adding the routes explicitly in the routes.rb can serve to allow for customization of the order of the routes. New apps can have the routes.rb generated with the active storage routes automagically inserted by default. |
This issue has been automatically marked as stale because it has not been commented on for at least three months. |
Can still reproduce on 5.2 stable |
This issue has been automatically marked as stale because it has not been commented on for at least three months. |
I can still reproduce on 5.2 stable. I am trying to redirect routing errors to root_path, and I have tried solutions at this stackoverflow link and this medium link, all with the same outcome: broken active_storage links to uploaded images. kieraneglin's suggestion above works like a charm. |
maybe, it's better to add the catch-all route after application initialization, as described here: |
Disabling match all in routes, until a better solution is found. See: rails/rails#31228
* Use active storage for users profile picture Added a new endpoint /me/profile Also on /me the user object has a profile_picture which has a timeout? We still have the older user.avatar * ActiveStorage: add route for /rails/active_storage Add full URL to .profile_picture Open up for CORS in development * ActiveStorage conflict with routes match all Disabling match all in routes, until a better solution is found. See: rails/rails#31228 * Gemfile: aws gem was added multiple times * Git info: .chomp was misplaced * Gemfile: remove GCS and /profile_url test endpoint * Storage: not using GC
This issue has been automatically marked as stale because it has not been commented on for at least three months. |
@rafaelfranca Thanks for the update. If no solution is proposed, would you be open to a PR that adds documentation/caveats around AS+catchall routes? |
This issue has been automatically marked as stale because it has not been commented on for at least three months. |
I am newbie to rails and this routing system but i have tried something like from wildcard routes |
Hi! My app frequently raises a I'd like to treat this cases with an error page or a json error case content type is json. So, a wrote this: Rails.application.routes.draw do
#... many things here
match '*unmatched', to: 'errors#route_not_found', via: :all
end class ErrorsController < ApplicationController
def route_not_found
respond_to do |format|
format.json { render json: { error: 'The request resource does not exist' }, status: :not_found }
format.html { redirect_to '/#/404' }
end
end
end Everything run as I expected except Active Storage. Reading all the content of this thread made me think if I'm not implementing the wrong solution for my problem. Is it really a bug in Rails? Or is there a way more correct to solve my problem? I suppose that I'm doing the wrong thing because it seems something common to have in almost any app. Thank you! |
Check out |
Why 2 major versions later does activestorage need it's own way outside of the conventions to route things whatsoever?? why is it not drawing routes like every single other engine and letting people mount them normally? that is the real solution |
For those that come in here on rails 7, I discovered a much better solution (other than actually fixing activestorage to not be non-conforming) that will guarantee that your catchall comes last in
|
I'm digging into Active Storage these days because I'm going to use it for a side project. To be honest, on behalf of the rails community, I'm embarrassed over what I'm learning. First I discovered that everyone can by default upload files and retrieve those files from your storage through direct uploads. The documentation is not mentioning this at all. On top of that the authentication example given by the docs disable all the active storage routing, which is an unnecessary trade-off. It will convince lots of devs that those routes are hard to guess anyway, and so they will leave the direct upload hole open for anyone to use - a bit like how mongodb was insecure by default. On top of that we have the routing which breaks catch-all routes for no reason other than "plug and play". I could live with this, if I was able to both cancel the "automagical" drawing of routes with the That such glaring issues have not been addressed at this point makes me worried if Active Storage is a solution I can trust. If it's even used by DHH and the likes, or if it's another glorified experiment that everyone then had to live with (like coffee script and webpacker). I'll consider making a PR for the solution I outlined with having a separate method draw the routes. It seems like it won't break current functionality. |
I just got bit by this trying to write a system test that needs these routes to interact with the Active Storage disk service, still occurs on main at 9e01d9. In order to help anyone who might find this via Google, what I was experiencing in my test was that images loaded via
Which I could see from
Anyway, I'm sure one of the workarounds above will fix this, but it does seem like this is a confusing enough failure state that it'd be worth attempting a refactor of how the ActiveStorage engine draws its routes |
Speaking of workarounds, here's the one that worked best for me while being minimally invasive. Changing the end of get "*path", to: "errors#not_found" To this: get "*path", to: "errors#not_found", constraints: lambda { |req|
!req.path.start_with? "/rails/active_storage"
} |
This will still let any request that starts with |
What do you think about this? main...justinko:rails:activestorage-routes In your app, you would just do: config.active_storage.draw_routes = false
# inside your app's routes.rb
draw "rails/active_storage" The routes are pretty complex so don't think |
seems reasonable! |
Seems like a simple and reasonable workaround to me 👍 |
Fixes rails#31228 Revert "Add the ability to explicitly load the ActiveStorage routes" This reverts commit 2faa138. Add the routes via method Try ActiveStorage::Routes fix routes_test.rb no instance_eval
Steps to reproduce
Using ActiveStorage, Webpacker, and React Router. Setup Rails routing for a catchall route
Expected behavior
Catchall Route should ignore ActiveStorage Routing
Actual behavior
This also picks up the ActiveStorage routing:
/rails/active_storage
, so the React Router incorrectly tries to route to the file.System configuration
Rails version:
5.2.0.alpha d3893ec
Ruby version:
2.4.2
The text was updated successfully, but these errors were encountered: