I'd like certain rails routes to only be accessible from localhost. In other words if you attempted to access that url from a non localhost connection you would be given a response equivalent to the route not existing.
Optimally some way of specifying routes as local in the routes.rb itself would be the cleanest solution but if there is some way to filter the request later at the controller level for example thats okay too.
If you want to specify that these urls exist only in a development environment, you can do just simple:
if Rails.env.development?
#your routes
end
But if your server in development mode is being accessed by others and you want to specify that these routes exist for localhost only then you can add constraint for domain:
if Rails.env.development?
resources :users, constraints: { domain: 'localhost' }
end
The file routes.rb contains special DSL for routes, but it's still ruby.
So, did you try put your routes in simple condition?
# routes.rb
if Rails.env.development?
# your special local routes definition
end
Related
Can we change the default 'permanent' url create from active storage to redirect to S3. Is something like rails/active_storage/representations/. I don't like the framework name in the url.
Thanks
UPDATE:
Recently, there was an addition which makes the route prefix configurable in Rails 6: https://guides.rubyonrails.org/6_0_release_notes.html#active-storage-notable-changes
It's just a matter of configuration:
Rails.application.configure do
config.active_storage.routes_prefix = '/whereever'
end
Unfortunately, the url is defined in ActiveStorage routes.rb without easy means to change:
get "/rails/active_storage/blobs/:signed_id/*filename" =>
"active_storage/blobs#show", as: :rails_service_blob
get "/rails/active_storage/representations/:signed_blob_id/:variation_key/*filename" =>
"active_storage/representations#show", as: :rails_blob_representation
One solution starting point I can think of is defining your own Routes in addition and overriding the "rails_blob_representation_path" or similar
get "/my_uploads/:signed_blob_id/:variation_key/*filename" =>
"active_storage/representations#show", as: :my_upload
and then overriding the path in a helper file and include the helper into the Named Helpers:
How to override routes path helper in rails?
module CustomUrlHelper
def rails_blob_representation(*args)
my_upload(*args)
end
end
# initializer etc.
Rails.application.routes.named_routes.url_helpers_module.send(:include, CustomUrlHelper)
The solution might need some adjustments though, I didn't tested it.
I hoped route constraints would allow me to have admin.example.com/widgets/ and example.com/admin/widgets/ be effectively the same, with the URL helper admin_widgets_path pointing to the correct one based on the current subdomain. However, the route helper seems to only point to one or the other regardless of constraints.
Am I doing something wrong? Is this a bug? Is there a better way to solve this problem?
A rails app with an example of the problem has been published here, but the relevant details are below.
My config/routes.rb
class Subdomains
# any domain that starts with 'admin.'
def self.admin?
-> (request) { request.host =~ /^admin\./ }
end
# any other domain
def self.primary?
-> (request) { !admin?.(request) }
end
end
Rails.application.routes.draw do
constraints(Subdomains.primary?) do
namespace :admin do
resources :widgets
end
end
constraints(Subdomains.admin?) do
scope module: "admin", as: :admin do
resources :widgets
end
end
root to: "admin/widgets#index"
end
My app/views/admin/widgets/index.html.erb
<%= link_to "Widgets", admin_widgets_url %>
In this configuration, admin_widgets_url always returns /admin/widgets/ which isn't a valid route on admin.example.com so clicking the link results in a routing error on that subdomain. If the admin subdomain constraint block is put first in the routes, then the URL helper always returns /widgets/, breaking the link on a non-admin domain.
The routes otherwise work, but not sure how to get the URL helpers to point to the correct one.
Your expectations are wrong - Rails reads the entire routes definition as part of the setup phase. This is also when the route helpers are created. The constraint is not actually evaluated until later when the request is matched.
Rails splits this into distinct phases to allow forking.
Instead you may need to override the route helpers.
Is it possible to split Rails 3.X routes.rb file?
We have so many resources it is difficult to find them. I would like to split at least APP and REST API routes.
Thanks!
You can do that:
routes.rb
require 'application_routes'
require 'rest_api_routes'
lib/application_routes.rb
YourApplication::Application.routes.draw do
# Application related routes
end
lib/rest_api_routes.rb
YourApplication::Application.routes.draw do
# REST API related routes
end
UPDATE: (This method has since been removed from Rails)
Rails edge just got a great addition, multiple route files:
# config/routes.rb
draw :admin
# config/routes/admin.rb
namespace :admin do
resources :posts
end
This will come handy for breaking down complex route files in large apps.
In Rails3, you can set the configs in config/application.rb
config.paths.config.routes.concat Dir[Rails.root.join("config/routes/*.rb")]
Rails 3.2.11
config.paths["config/routes"].concat Dir[Rails.root.join("config/routes/*.rb")]
Is there a way to remove routes specified in a gem in Rails 3? The exception logger gem specifies routes which I don't want. I need to specify constraints on the routes like so:
scope :constraints => {:subdomain => 'secure', :protocol => 'https'} do
collection do
post :query
post :destroy_all
get :feed
end
end
Based on the Rails Engine docs, I thought I could create a monkey patch and add a routes file with no routes specified to the paths["config/routes"].paths Array but the file doesn't get added to ExceptionLogger::Engine.paths["config/routes"].paths
File: config/initializers/exception_logger_hacks.rb
ExceptionLogger::Engine.paths["config/routes"].paths.unshift(File.expand_path(File.join(File.dirname(__FILE__), "exception_logger_routes.rb")))
Am I way off base here? Maybe there is a better way of doing this?
It is possible to prevent Rails from loading the routes of a specific gem, this way none of the gem routes are added, so you will have to add the ones you want manually:
Add an initializer in application.rb like this:
class Application < Rails::Application
...
initializer "myinitializer", :after => "add_routing_paths" do |app|
app.routes_reloader.paths.delete_if{ |path| path.include?("NAME_OF_GEM_GOES_HERE") }
end
Here's one way that's worked for me.
It doesn't "remove" routes but lets you take control of where they match. You probably want every route requested to match something, even if it is a catch all 404 at the bottom.
Your application routes (MyApp/config/routes.rb) will be loaded first (unless you've modified the default load process). And routes matched first will take precedence.
So you could redefine the routes you want to block explicitely, or block them with a catch all route at the bottom of YourApp/config/routes.rb file.
Named routes, unfortunately, seem to follow ruby's "last definition wins" rule. So if the routes are named and your app or the engine uses those names, you need to define the routes both first (so yours match first), and last (so named routes point as you intended, not as the engine defines.)
To redefine the engine's routes after the engine adds them, create a file called something like
# config/named_routes_overrides.rb
Rails.application.routes.draw do
# put your named routes here, which you also included in config/routes.rb
end
# config/application.rb
class Application < Rails::Application
# ...
initializer 'add named route overrides' do |app|
app.routes_reloader.paths << File.expand_path('../named_routes_overrides.rb',__FILE__)
# this seems to cause these extra routes to be loaded last, so they will define named routes last.
end
end
You can test this routing sandwich in the console:
> Rails.application.routes.url_helpers.my_named_route_path
=> # before your fix, this will be the engine's named route, since it was defined last.
> Rails.application.routes.recognize_path("/route/you/want/to/stop/gem/from/controlling")
=> # before your fix, this will route to the controller and method you defined, rather than what the engine defined, because your route comes first.
After your fix, these calls should match each other.
(I posted this originally on the refinery gem google group here: https://groups.google.com/forum/?fromgroups#!topic/refinery-cms/N5F-Insm9co)
We are on Rails 2.3.
What is the upper bound on the number of routes Routes.rb can contain before performance is affected?
What are the key changes you made to the default Routes file created by scaffolding?
We like the default scaffolding in development since we can easily access/modify objects from the web as opposed to the database. However, this configuration is not tenable for a production environment. Is there a way to "activate" certain routes while in development?
One thing I always do is if you are doing resources, I always limit the routes by doing something like:
map.resources :comments, :only => [:create, :destroy, :index]
You can just put the following in your routes.rb file
if ENV['RAILS_ENV'] == 'production'
#production routes
else
#development routes
end