How to have multiple constraints in Rails routes.rb? - ruby-on-rails

I would like a rails route that takes 2 constraints into consideration. How can this be done? The two constraints
match ':id' => 'pages#temp', :constraints => { :uuid => /[A-Za-z\d]([-\w]{,498}[A-Za-z\d])?/ }
root :to => 'pages#temp', :constraints => lambda {|r| r.env["warden"].authenticate? }
How can I have one route like so with both of the constraints in place? Thanks
match ':id' => 'pages#temp', :constraints =>

I guess you will have to make a custom constraints class and put all your constraints there. Refer the advanced constraints in rails guides(Link below) for more information.
http://guides.rubyonrails.org/routing.html#advanced-constraints

I had to use multiple constraints for subdomains and usernames. I used a block to solve the issues:
constraints subdomain: ['survey', 'survey.staging'] do
match "/(:username)", to: "responses#index", constraints: { username: /[0-z\.\-\_]+/ }, :via => [:get, :post]
end
So you might try something like this:
constraints id: { uuid: /[A-Za-z\d]([-\w]{,498}[A-Za-z\d])?/ } do
match '/:id' to: 'pages#temp', constraints: lambda {|r| r.env["warden"].authenticate? }
end

Related

Rails Routing Constraint - Limit paths to development

I am trying to add a constraints to our error-routes so that requests to certain routes would not get redirected to a 404-page if we're working on our app in development.
match '*unmatched_route', :to => 'application#handle_404', via: :all, constraints: lambda { |request| !request.url["/rails/info"] }
This is the rule we currently have in place. All "invalid" routes being redirected to a 404-page. Now I want to upgrade this to only allow access to /rails/info/* if the app is in development-mode.
I tried the following:
match '*unmatched_route', :to => 'application#handle_404', via: :all, constraints: lambda { |request| !request.url["/rails/info"] && !Rails.env.development? }
I am not sure where exactly the problem is. The addition inside the constraint does not seem to have any effect, thus I believe I am using the constraint entirely wrong.
Thanks in advance!
Might not be as elegant, but you could put the route inside a unless block, like this:
unless Rails.env.development?
match '*unmatched_route', :to => 'application#handle_404', via: :all, constraints: lambda { |request| !request.url["/rails/info"] }
end

Rails Route Constraint

match '/:question_id', :to => 'welcome#dashboard', :via => [:get], constraint: { question_id: /\d+/ }
I don't know why this routing rule is matching paths like
localhost/assets
because I added the numeric constraint to only matching digits.
The option is contstraints.
match '/:question_id', :to => 'welcome#dashboard', :via => [:get], constraints: { question_id: /\d+/ }

Cant define root route more than once in Rails 4

I've got the following in my routes file:
scope :constraints => lambda{ |req| req.session[:user_id].present? } do
root "users#show"
end
scope :constraints => lambda{ |req| req.session[:admin_id].present? } do
root "brands#index"
end
root "sessions#new"
This code worked fine in Rails 3, but when I use it in Rails 4 I get the following error message:
Invalid route name, already in use 'root' (ArgumentError).
You may have defined two routes with the same name using the ':as' option
Is there a way round this? What has changed?
As #vimsha pointed out, it's a known issue and in my case the best fix was to do the following:
scope :constraints => lambda{ |req| req.session[:user_id].present? } do
match '/', to: "users#index", via: :get
end
scope :constraints => lambda{ |req| req.session[:admin_id].present? } do
match '/', to: "brands#index", via: :get
end
root "sessions#new"
Alles im ordinem.

Format constraint in wildcard route

I have a CMS style application where the user can set a custom url and it routes to our "content_pages" controller.
To support this we have 3 wildcard routes defined.
I'm trying to constrain these wildcards so that they only respond to requests where the format is html, json, or xml and nothing else. This stems out of a problem where a missing favicon.ico results in a series of queries and web requests because it routes to the content_pages controller and then 404s.
Here's what I have so far but the constraint simply doesn't work. (favicon still routes)
get "/:id/edit", to: "content_pages#edit", :constraints => {:id => /.*/, :format => "[html|xml|json]"}, as: :edit_content_page
put "/:id", to: "content_pages#update", :constraints => {:id => /.*/, :format => "[html|xml|json]"}, as: :content_page
get "/:id", to: "content_pages#show", :constraints => {:id => /.*/, :format => "[html|xml|json]"}, as: :content_page
I also tried putting this into a custom constraint class but then the actions on content_pages that arent included here (like /content_pages which routes to index) don't render.
Here's the earlier resource statement that wires up the other actions.
resources :content_pages, except: [:get, :edit, :update] do
collection do
get :get_url
end
end
Any thoughts on how i can make this constraint apply without breaking our other, non-constrained actions?
If the only file type you want to exclude is .ico, then you could update your :id constraint to explicitly exclude it:
get "/:id", to: "content_pages#show", :constraints => {:id => /.+?(?<!ico)/, :format => /(html|xml|json)/}, as: :content_page
The simplest solution to this is to put a blank favicon.ico in your public directory.
This has the side benefit of allowing you to tidy up the routes:
get "/:id/edit", to: "content_pages#edit", as: :edit_content_page
put "/:id", to: "content_pages#update", as: :content_page
get "/:id", to: "content_pages#show", as: :content_page

Rails 3: Replace /users/username/something for /username/something

I already have a route to match /username for the users show page. However, when I add another action, for example: followers and following as below:
resources :users, :only => [:show] do
get :following, :followers
end
I get the URL /users/username/following instead of /username/following.
How can I make all the /users/username URL's be matched as /username/etc.. ?
Here's my /username route:
match '/:id' => 'users#show', :constraints => { :id => /[a-zA-Z0-9\-_]*/ }, :as => "user_profile"
thank you.
Edit:
I have fixed this by adding
match '/:id/following' => 'users#show/following', :as => "user_following"
match '/:id/followed' => 'users#show/following', :as => "user_followers"
But I'm not sure if that's the best solution. What I'd really want is a default route that would match all /:id/:action to the appropriate action omitting the /users.
I have fixed this by adding
match '/:id/following' => 'users#show/following', :as => "user_following"
match '/:id/followed' => 'users#show/following', :as => "user_followers"
But I'm not sure if that's the best solution. What I'd really want is a default route that would match all /:id/:action to the appropriate action omitting the /users.
Near the bottom
match ':id/:action', :controller => :users

Resources