:as in rails routes.rb
The :as option forms a named route.
Usually it's used in a non-root route. For example:
match '/search' => 'search#search', :as => 'search' # SearchController#search
You could then do something like:
<%= link_to search_path, 'Click Here to Search!' %>
search_path
and search_url
are defined because of the :as
For a root route, you don't really need :as
because the the URL helpers root_path
and root_url
are defined for you by Rails.
Ruby on rails routes - what does the as do?
In routes as:
option is used to make url or path helpers for that particular route. If you look at your route:
get '/patients/:id', to: 'patients#show', as: 'patient'
You have specified as: 'patient'
which will enable rails to make patient_path
and patient_url
helpers
patient_path will give you /patient/:id and patient_url will give you domain/patient/:id
If you run rake routes in your terminal it will list all the routes of your application with there corresponding helper methods. For details checkout path and url helpers
correct way to use routes.rb namespace rails?
Answering your question
Alright, namespace :something
is a shorthand for scope 'something', module: 'something', as: 'something'
Now your declaration is very ambiguous, because you don't specify a controller. Typical declarations look like (assume you have a controller controllers/backend/some_resources_controller.rb
and you want to generate default routes)
namespace :backend do
resources :some_resources
end
Now what you did
namespace :backend
get 'index'
end
is really ambiguous and I'm not surprised it doesn't do what you want. Basically you just tell rails to "look inside subfolder 'backend' and define the route 'index'". oO ? Which file/controller are we even talking about ?
What is your backend_controller.rb
supposed to do ? Is it some kind of Control Panel ? Dashboard ? If so you're probably gonna have a lot of non-CRUD actions, but anyways you should go for the following syntax
namespace :backend
# Below line of code will auto-generate the `index` for /backend/backend_controller
resource :backend, only: [:index], path: '' do # we need " path: '' " otherwise we'll have https://xxx/backend/backend/dashboard
# If you have non-CRUD actions, put them here !
get 'dashboard' # https://xxx/backend/dashboard
...
end
# However, this will create URLs like "https://xxx/backend/dashboard", etc.
# If you want to redirect https://xxx/backend/ to your backend_controller#index, use root
root to: 'backend#index' # https://xxx/backend/
end
Last thing as mentionned by other guys, when you namespace a file like your Backend_controller inside /backend/
subfolder, you must rename the class like (/controllers/backend/backend_controller
)
class Backend::BackendController < ApplicationController
Remark : if you only have like one or two controller actions, instead of using the resource
method, you can declare singular resources
namespace :backend do
root to: 'backend#dashboard'
get 'dashboard', to: 'backend#dashboard' # singular resource
end
An Example of what you may actually really want to do...
I'm not sure you are clear yourself about what you want to do. As an example, here is my architecture
Files
/controllers/application_controller.rb
/controllers/backend_controller.rb
/controllers/backend/static_pages_controller.rb
/controllers/backend/***.rb
The class /controllers/backend_controller.rb
will not serve any action, but will override ApplicationController to tune it for backend access (but maybe you don't need to do so)
class BackendController < ApplicationController
# Do you need to change user_access method ? Or any other backend-wide config ?
# If so put this config here, otherwise leave empty
end
Now for every file that goes in the /backend/
subfolder, I inherit the backend_controller
class Backend::StaticPagesController < BackendController
def index
end
# Note : if your index is some kind of dashboard, instead I would declare
def dashboard
end
end
class Backend::SomeResourcesController < BackendController
...
end
Routes
namespace :backend do
root to 'static_pages#index' # https://xxxx/backend/
resource :static_pages, only: [:index], path: '' # https://xxxx/backend/index
resources :some_resources
end
If you choose the dashboard solution in your controller, write instead :
namespace :backend do
root to: static_pages#dashboard # https://xxxx/backend/
resource :static_pages, path: '', only: [] do
get 'dashboard' # https://xxxx/backend/dashboard
end
resources :some_resources
end
Rails: routes.rb and omitting the controller name
After browsing through some documentation, and finding nothing relevant, I had a look at the source. It seems that the match
method (which get
is a shorthand for) is calling get_to_from_path
(defined here), which extracts the controller and method information from the provided path
, if to:
isn't provided.
So, for this scenario, this
get 'static_pages/home'
get 'static_pages/help'
gets mapped to static_pages#home
, and static_pages#help
. Using dashes (-
) instead of underscores (_
) in the path would work as well.
It is weird that this functionality is not documented, and more so that it is used in a tutorial without explanation.
Accessing URL helpers in routes.rb
I know I'm a little late here, but this question is one of the top hits when googling "use url_helpers in routes.rb", and I initially found it when I had stumbled upon this problem, so I'd like to share my solution.
As @martinjlowm mentioned in his answer, one cannot use URL helpers when drawing new routes. However, there is one way to define a redirecting route rule using URL helpers. The thing is, ActionDispatch::Routing::Redirection#redirect can take a block (or a #call
-able), which is later (when the user hits the route) invoked with two parameters, params and request, to return a new route, a string. And because the routes are properly drawn at that moment, it is completely valid to call URL helpers inside the block!
get 'privacypolicy.php', to: redirect { |_params, _request|
Rails.application.routes.url_helpers.privacy_policy_path
}
Furthermore, we can employ Ruby metaprogramming facilities to add some sugar:
class UrlHelpersRedirector
def self.method_missing(method, *args, **kwargs) # rubocop:disable Style/MethodMissing
new(method, args, kwargs)
end
def initialize(url_helper, args, kwargs)
@url_helper = url_helper
@args = args
@kwargs = kwargs
end
def call(_params, _request)
url_helpers.public_send(@url_helper, *@args, **@kwargs)
end
private
def url_helpers
Rails.application.routes.url_helpers
end
end
# ...
Rails.application.routes.draw do
get 'privacypolicy.php', to: redirect(UrlHelperRedirector.privacy_policy_path)
end
Subdomains in routes.rb
Constraints in routes.rb
allow you to restrict when routes should or shouldn't be matched, returning a 404 in the event that they do not.
You can do this on a per-route basis for params like so:
get 'products/:category', to: "products#index", category: /(fruit|electronics|medicine)/, as: :products
This would allow requests to http://yourdomain.com/products/fruit
but not to http://yourdomain.com/products/vehicles
for example. Accessing any forbidden domains would provide you with a 404 response.
You can provide generic constraints to a bunch of different routes by enclosing them in a constraints block, like so:
constraints ->(req) { Site.exists?(subdomain: req.subdomain) } do
resources :articles, path: "blog", only: [:index, :show]
...
end
So here, we're checking that a Site
record exists with the subdomain provided. If not, we return a 404.
i have to put a parameter in routes.rb
Try to change this on routes.rb
get 'api/forecast/service_name:' , to: 'api/forecasts#index'
How to setup Rails routes.rb for Vanity URL without requiring a prefix
Basic code to get you started:
# config/routes.rb
Rails.application.routes.draw do
resources :posts
resources :authors
constraints(PostUrlConstrainer.new) do
get "/:id", to: "posts#show"
end
end
# app/constraints/post_url_constrainer.rb
class PostUrlConstrainer
def matches?(request)
title = request.path_parameters[:id]
Post.find_by(title: title)
end
end
# app/controllers/posts_controller.rb
def set_post
@post = Post.find_by(title: params[:id])
end
Related article: Pretty, short urls for every route in your Rails app - Arkency Blog
Searching for rails url constraint
seems to help.
Why does order matter in Rails routes.rb when using resources?
The error you're getting is because rails tries to match routes starting from the top down. If you're trying to add a custom route to an existing resource, the easier way is to do this. collection
is if you want to use it on the group, member
is if you want to add a custom route to an individual resource.
resources :coupons do
collection do
get 'redeem_coupon'
end
end
Related Topics
How to Compare Strings Ignoring the Case
Ruby: How to Add "# Encoding: Utf-8" Automatically
How to Remove Permission Denied @ Rb_Sysopen - Gem Install Error
How to Convert a Ruby Hash to Xml
Can You Eval Code in the Context of a Caller in Ruby
How to Run a Single Rspec Test
How to Have Multiple Versions of Ruby and Rails, and Their Combinations on Windows
Rails Resque Workers Fail with Pgerror: Server Closed the Connection Unexpectedly
Getting an Ascii Character Code in Ruby Using '' (Question Mark) Fails
How to Print Out the Contents of an Object in Rails for Easy Debugging
Couldn't Require Openssl in Ruby
Rails - Params with "Dot" (E.G. /Google.Com)
Typing 'Rails Console' Doesn't Start
Has_Many :Through with Counter_Cache
How to Merge Two Hashes Without Overwritten Duplicate Keys in Ruby