Map routes into other routes in Rails - ruby-on-rails

I'm having some troubles with routes in Ruby on Rails v5.2.0
Currently, I have a resource called users, so that I have a controller which takes actions (for example index) whenever I start my server in localhost on port 3000 and type in my browser
localhost:3000/users/
Is there an easy way to map the requests for this resource to the app root?Basically, I'm trying to achieve this:
localhost:3000/users/ --> localhost:3000/
localhost:3000/users/new/ --> localhost:3000/new/
This is how my routes.rb file looks like right now:
Rails.application.routes.draw do
devise_for :users
get 'landing/index'
get 'welcome/index'
resources :users
root to: 'landing#index'
end

Add the following lines to your routes.rb file
Change
root to: 'landing#index'
to
root "users#index"`
and add the line
get "/new" => "users#new"
Also if you want to learn more on routing, here is the link
http://guides.rubyonrails.org/routing.html

TLDR - Rails doesn't have a root model generator for routing
You can manually create the individuals routes
get :new, to: "users#new", as: "new_user"
...
However while using the rails generators resources you are just specifying a shorthand for
scope :model do
get :new, to: "model#new", as: "new_model"
...
end
You can checkout the rails guide to routing for more specifics on explicit creation
http://guides.rubyonrails.org/routing.html
HACKY SOLUTION
root to: "users#index", as: "users"
get :new, to: "users#new", as: "new_user"
post "/", to: "users#create"
scope ":id" do
root to: "users#show"
get :edit, to: "users#edit", as: "edit_user"
patch "/", to: "users#update"
...
end

It looks that what you want is to 'mute' users from the url. An option for this is to call path: '' on users like this:
Rails.application.routes.draw do
devise_for :users
get 'landing/index'
get 'welcome/index'
resources :users, path: '' # <-- HERE
root to: 'landing#index'
end
The value you give to path: is going to replace the resource name.
In this scenario users is being replaced with an empty string '', but it could be any other string.
This will remove users. However, you must consider that root to: 'landing#index AND users#index are both pointing to localhost:3000/
Without knowing your app, an option to solve this scenario, could be to have landing#index as root for gustes (not authenticated users) and users#index as a root for authenticated users.

Related

Ruby on Rails Devise id='sign up'

So a few people have had this problem, but none of their code actually matches mine so their solutions aren't working.
Basically, whenever I try to access /users/:id it passes in the params correctly {'id' => '1'}, but then the page errors out on 'no user with id='sign_out'
My routes:
Rails.application.routes.draw do
devise_for :users, path: 'devise'
get 'sessions/new'
get 'intro', to: 'index#intro'
root 'index#intro'
authenticated :user do
root 'index#homepage', as: :authenticated_root
end
devise_scope :user do
get '/start', to: 'devise/sessions#new', as: "login"
get '/devise/sign_out', to: 'devise/sessions#destroy', as: "logout"
get '/signup', to: 'users#new', as: "signup"
end
get '/forgotPassword', to: 'index#forgotPassword'
get '/homepage', to: 'index#homepage'
get '/meetUs', to: 'index#meetUs'
get '/makeSuggestion', to: 'index#makeSuggestion'
get 'profile', to: 'index#profile'
resources :suggestions
resources :rewards
resources :users
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
Code in controller erroring out:
# GET /users/1
# GET /users/1.json
def show
#users = User.find(params[:id])
end
I'm pretty sure the issue has something to do with the routes thinking /users is both a resource of mine and of devise. But I don't know how to tell it to use the default route rails made as opposed to the one devise made.
If anyone could help, and try and explain why it's happening, that'd be great. Thanks in advance!
edit: Picks of the error and trace

How can I use wildcards in my routes for all of them excepted for one pattern?

I would like to use React-Router to handle the majority of my pages from the visitor part and create a Single Page Application in the mean time. However, I would like to make sure that if the user types /admin, he wouldn't get "redirected" to the root_path
So far I only managed to either pass everything to a wildcard or make "compartiments" as follows:
root 'home#index'
# example 1
get '/*path' => 'home#index'
get '/articles' => 'home#articles_index'
# example 2
get '/articles/*all' => 'home#articles_index'
# vain try 1
get '/*path' => 'home#index', except: :admin
# vain try 2
get '/*path' => 'home#index', except: '/admin'
I found out about the constraints, but I realized it's to make sure the url is correctly passed (ie, integer instead of strings) but it doesn't "blacklist" urls.
Any idea?
Thank you in advance
You can use wildcard segment with constraints for this purpose. For example:
# config/routes.rb
Rails.application.routes.draw do
root to: 'home#index'
get '*subroute', to: 'home#index', constraints: { subroute: /(?!admin|login|logout).*/ }
# all another routes below
end
This will pass any request to home#index unless there is 'admin' or 'login' or 'logout' in URL.

Weird path_helper error when using english locale

I am experiencing a weird error that I no longer want to work around but understand.
When recently adding an english version of our homepage, I found that I can't generate the pathes as I do for the german locale:
2.3.0 :023 > I18n.available_locales
=> [:de, :en]
2.3.0 :019 > apps_path(locale: :de)
=> "/de/apps"
2.3.0 :020 > apps_path(locale: :en)
ActionController::UrlGenerationError: No route matches
{:action=>"apps", :controller=>"pages", :locale=>:en} missing required keys: [:locale]
As I said, I was able to work around that, by using either url_for or – when sticking with our example apps_en_path.
But I wanna know what causes this weird problem.
EDIT
A git bisect session helped me to find out that this happens since I added the route-translater gem to my project. Besides this issue it works fine for us.
I had this settings (in development.rb):
# RouteTranslator.config
config.force_locale = true
config.locale_param_key = :locale
My routes.rb:
require_relative "#{Rails.root}/app/route_constraints/can_access_devops"
Rails.application.routes.draw do
get 'health', to: 'health#show'
# Redirect requests with trailing 'null'
get '/*path/null', to: redirect('/%{path}')
namespace :admin do
root to: redirect('/admin/magazine_articles')
resources :jobs
resources :users
resources :magazine_categories
resources :magazine_articles
resources :media_assets
resources :advertisements do
member do
get 'preview'
end
end
namespace :devops do
authenticate :user do
constraints CanAccessDevOps do
mount PgHero::Engine, at: '/pghero'
end
end
end
end
scope '/:locale', locale: /#{I18n.available_locales.join("|")}/ do
root to: 'pages#home'
localized do
devise_for :users, controllers: { sessions: 'sessions' }
# redirect terms of use to cockpit; this is required because
# the packaging has a link that should point to cockpit
get 'home', to: 'pages#home'
get 'imprint', to: 'pages#imprint', as: 'imprint'
get 'lottery', to: 'pages#lottery', as: 'lottery'
get 'privacy', to: 'pages#privacy', as: 'privacy'
get 'terms', to: 'pages#terms', as: 'terms'
get 'faq', to: 'pages#faq', as: 'faq'
get 'declaration-of-conformity', to: 'pages#declaration_of_conformity', as: 'declaration_of_conformity'
# Contact Page / Support Cases
resource :support_cases, only: [:create, :new], path_names: { new: 'new_support_case' } do
get :success, on: :collection
end
# redirect using the url helper to respect route localization. ugly but it works
get 'kontakt', to: redirect { |_, _| Rails.application.routes.url_helpers.new_support_cases_path }
# Workshop
get 'workshop', to: 'pages#workshop', as: 'workshop'
get 'autofit', to: 'pages#autofit', as: 'autofit'
# App-related
get 'app', to: 'pages#app', as: 'app'
get 'apps', to: 'pages#apps', as: 'apps'
get 'cars', to: 'pages#cars', as: 'cars'
get 'roadmap', to: 'pages#roadmap', as: 'roadmap'
# Press Material
get 'press', to: 'press_materials#index', as: 'press_materials'
get 'press/brand', to: 'press_materials#brand', as: 'press_materials_brand'
get 'press/team', to: 'press_materials#team', as: 'press_materials_team'
get 'press/app', to: 'press_materials#app', as: 'press_materials_app'
get 'press/pace-link', to: 'press_materials#pace_link', as: 'press_materials_pace_link'
get 'press/graphics', to: 'press_materials#graphics', as: 'press_materials_graphics'
# Feature pages
get 'features/automatic-emergency-call', to: 'features#ecall', as: 'ecall'
get 'features/fuel-saving-trainer', to: 'features#fuel_saving_trainer', as: 'fuel_saving_trainer'
get 'features/trouble-code-analysis', to: 'features#trouble_code_analysis', as: 'trouble_code_analysis'
get 'features/find-my-car', to: 'features#find_my_car', as: 'find_my_car'
get 'features/logbook', to: 'features#logbook', as: 'logbook'
# old route – preserved as there might be old links somewhere pointing at this
get 'features/automatisches-fahrtenbuch', to: 'features#automatic_logbook'
# actual route: find-the-cheapest-gas-station
get 'features/gas-station-finder', to: 'features#gas_station_finder', as: 'gas_station_finder'
get 'features/fuel-cost-tracking', to: 'features#fuel_cost_tracking', as: 'fuel_cost_tracking'
get 'features/performance-monitor', to: 'features#performance_monitor', as: 'performance_monitor'
get 'features/traffic-monitor', to: 'features#traffic_monitor', as: 'traffic_monitor'
# Endpoints for car finder
get 'cars/query', to: 'cars#identify'
get 'cars/:id', to: 'cars#show'
# Job adverts
get 'jobs', to: 'jobs#index', as: 'jobs'
get 'jobs/:slug', to: 'jobs#show', as: 'job'
# Newsletter related routes
post 'newsletter-sign-up', to: 'subscribers#newsletter_create', as: 'newsletter'
get 'newsletter-confirmation(/:list)', to: 'subscribers#newsletter_after_confirm'
end
# Routes that we want to have under the german locale, but without translated route go here:
# Magazine
scope 'magazin' do
get '', to: 'magazine#index', as: 'magazine', constraints: { locale: 'de' }
# Redirect path without locale to locale equivalent path
get '/*path', to: redirect("/#{I18n.locale}/%{path}"),
constraints: lambda { |req|
!req.path.match(%r{^\/(404|422|500)$}) &&
!req.path.match(%r{^\/(#{I18n.available_locales.join("|")})\/.*})
}
# Redirect root to detected locale
root to: 'application#redirect_to_localized_root', as: :redirected_root
end
I had a quick play through with your routes, and I had I similar issue with the de route. I think the apps_path route you're getting will only allow your default locale as param.
Adding the following option solved it for me:
RouteTranslator.config do |config|
config.generate_unlocalized_routes = true
end
This will generate the unlocalized routes correctly, so you can pass multiple locales to apps_path.
There is nothing that looks super suspicious to me except this localized block. Does this come from some gem? If so does the apps_path(locale: 'en') request work outside of this localized block?
You can use Rails.application.routes.url_helpers.app_path(locale: :en) on the console to test this after adjusting the routes file.

Placing User ID's within Routes with Devise

I currently have a default devise set up and wanting to put the user id's within my logged in routes and leave the others alone such as Welcome,FAQ, About us etc.
Such as
www.example.com/user-id/offers
My Current Routes File
devise_for :users
mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
resources :offers do
member do
put :tourcomplete
end
end
resources :categories, only: :show
root 'welcome#index'
get '/balance', to: 'balance#show', as: 'balance'
patch '/balance', to: 'balance#paypal', as: 'balance_paypal'
patch '/withdraw', to: 'balance#withdraw', as: 'balance_withdraw'
I can't find any docs on this and my previous answer to a similar question was very vague and not helpful.
Thanks
You will need to use a nested routes:
resources :users do
resources :offers do
member do
put :tourcomplete
end
end
end
so now your routes will be /users/:id/offers, run rake routes to check your routes.
if you want to exclude users then you will have to specify the route yourself:
match ':user_id/offers' => 'offers#index'

Why rails app is redirecting unexpectedly instead of matching the route?

I asked this question earlier and thought it was fixed, but it's not. Previous question here
My problem is I am trying to set my routes so that when I type in
localhost:3000/sites/admin
It should redirect to
localhost:3000/en/sites/admin
here is my routes.rb file
scope ":locale", locale: /#{I18n.available_locales.join("|")}/ do
get "log_out" => "sessions#destroy", as: "log_out"
get "log_in" => "sessions#new", as: "log_in"
resources :sites, except: [:new, :edit, :index, :show, :update, :destroy, :create] do
collection do
get :home
get :about_us
get :faq
get :discounts
get :services
get :contact_us
get :admin
get :posts
end
end
resources :users
resources :abouts
resources :sessions
resources :coupons
resources :monthly_posts
resources :reviews
resources :categories do
collection { post :sort }
resources :children, :controller => :categories, :only => [:index, :new, :create, :new_subcategory]
end
resources :products do
member do
put :move_up
put :move_down
end
end
resources :faqs do
collection { post :sort }
end
root :to => 'sites#home'
match "/savesort" => 'sites#savesort'
end
match '', to: redirect("/#{I18n.default_locale}")
match '*path', to: redirect("/#{I18n.default_locale}/%{path}")
But as of right now, it redirects to /en/en/en/en/en/en/en/en/en/en/sites/admin (adds en until browser complains).
Any thoughts why it keeps adding /en?
Edit:
The answer is great, thanks. Can you help me diagnose the root route?
root to: redirect("#{/#{I18n.default_locale}") # handles /
I know redirects is looking for something like
redirect("www.example.com")
So that leaves this part
#{/#{I18n.default_locale}
The #{ is using rubys string interpolation, right? i'm not sure what that { is doing though.
So then we have
/#{I18n.default_locale}
Which is also using string interpolation and to print out the value of I18n.default_locale?
Hopefully that makes sense, I really really appreciate the help, I am learning a lot.
Edit 2:
I changed the line from
root to: redirect("#{/#{I18n.default_locale}") # handles /
to
root to: redirect("/#{I18n.default_locale}") # handles /
But i'm not sure if thats right. Now i'm getting the error
uninitialized constant LocaleController
I know it's getting the error from the root to: "locale#root", but i thought the locale# would come from the scope.
I'll continue playing with it and let you know any progress.
Here is a new link to my routes file https://gist.github.com/2332198
We meet again, ruevaughn. :)
I created a test rails app and the following minimal example works for me:
scope ":locale", locale: /#{I18n.available_locales.join("|")}/ do
resources :sites do
collection do
get :admin
end
end
root to: "locale#root" # handles /en/
match "*path", to: "locale#not_found" # handles /en/fake/path/whatever
end
root to: redirect("/#{I18n.default_locale}") # handles /
match '*path', to: redirect("/#{I18n.default_locale}/%{path}") # handles /not-a-locale/anything
When using Rails 4.0.x that %{path} in the redirect will escape slashes in the path, so you will get an infinite loop redirecting to /en/en%2Fen%2Fen%2Fen...
Just in case someone, like me, is looking for a Rails-4-suitable solution, this is what I found to be working without problems, even with more complex paths to be redirected:
# Redirect root to /:locale if needed
root to: redirect("/#{I18n.locale}", status: 301)
# Match missing locale paths to /:locale/path
# handling additional formats and/or get params
match '*path', to: (redirect(status: 307) do |params,request|
sub_params = request.params.except :path
if sub_params.size > 0
format = sub_params[:format]
sub_params.except! :format
if format.present?
"/#{I18n.locale}/#{params[:path]}.#{format}?#{sub_params.to_query}"
else
"/#{I18n.locale}/#{params[:path]}?#{sub_params.to_query}"
end
else
"/#{I18n.locale}/#{params[:path]}"
end
end), via: :all
# Redirect to custom root if all previous matches fail
match '', to: redirect("/#{I18n.locale}", status: 301), via: :all

Resources