I have this code in routes.rb.
scope ":locale", :locale => /es/ do
match "inicio" => "home#index", :as => "home"
match "acerca-de" => "about#index", :as => "about"
match "servicios" => "services#index", :as => "services"
match "blog" => "blog#index", :as => "blog"
match "contacto" => "contact#index", :as => "contact"
end
scope ":locale", :locale => /en/ do
match "home" => "home#index", :as => "home"
match "about" => "about#index", :as => "about"
match "services" => "services#index", :as => "services"
match "blog" => "blog#index", :as => "blog"
match "contact" => "contact#index", :as => "contact"
end
What I'm trying to do is have a route like /es/acerca-de and /en/about which use the same controller and have the same url_path() so when I'm at spanish language the about_path() sends you to /en/about but when I'm at english language the about_path() sends you to /es/acerca-de.
Done!
I the answer was practically in the ruby on rails guides...
This is the code in routes.rb
scope ":locale", :locale => /es|en/ do
match "inicio" => "home#index", :as => "home"
match "acerca-de" => "about#index", :as => "about"
match "servicios" => "services#index", :as => "services"
match "blog" => "blog#index", :as => "blog"
match "contacto" => "contact#index", :as => "contact"
end
and added this in application_controller
class ApplicationController < ActionController::Base
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
Saba::Application.reload_routes!
end
Related
In my application controller, I am forcing locale handling as a before filter:
before_filter :set_locale
def set_locale
#I18n.default_locale is en
I18n.locale = extract_locale_from_tld || I18n.default_locale
end
def extract_locale_from_tld
parsed_locale = params[:locale] || ((lang = request.env['HTTP_ACCEPT_LANGUAGE']) && lang[/^[a-z]{2}/])
#so, english is the default language.
parsed_locale= 'en' if parsed_locale.nil?
I18n.available_locales.include?(parsed_locale.to_sym) ? parsed_locale : nil
end
However, if I tried to visit http://localhost:3000/ko/lab it would result into routing error which is error 404 eventually.
Any locale out of the following locates will result into routing error:
Any advice?
EDIT
My route.er:
# -*- encoding : utf-8 -*-
MyApp::Application.routes.draw do
mount Alchemy::Engine => 'blog'
Rails.application.routes.draw do
filter :pagination, :uuid, :locale
end
devise_for :users, :controllers => { :omniauth_callbacks => "callbacks",
:sessions => "users/sessions",
:registrations => "users/registrations"}
resources :authentications
resources :experiments
get 'experiments/:id/info_edit' => 'experiments#info_edit',:constraints => { :id => /\d+/ }
get 'sitemap.xml', :to => 'sitemap#index', :defaults => {:format => 'xml'}
match 'lang' => 'home#set_lang', :via => [:get]
#match 'free_trial' => 'home#free_trial', :via => [:get]
match 'useful_links' => 'home#useful_links', :via => [:get]
match 'home' => 'home#home', :via => [:get]
match 'contact-us' => 'contact#new', :as => 'contact_us', :via => :get
match 'contact' => 'contact#create', :as => 'contact', :via => :post
match 'dashboard' => 'experiments#index', :via => [:get]
post 'notifications' => 'subscriptions#instant_payment_notification'
match 'users_experiments' => 'experiments#users_experiments', :via => [:get]
match 'hire_us' => 'home#hire_us', :via => [:get]
get 'lab' => 'experiments#lab'
get 'experiments/:id/review-edit' => 'experiments#review', :as => :review
get 'experiments/:id/cancel-edit' => 'experiments#cancel_edit', :as => :cancel_edit
get 'experiments/:id/approve-edit' => 'experiments#approve', :as => :approve
get 'experiments/:id/reject-edit' => 'experiments#reject', :as => :reject
get 'experiments/:id/profile' => 'experiments#profile', :as => :profile
match 'amazon' => 'experiments#amazon', :via => [:get]
match 'trial_account' => 'home#trial_account', :via => [:get]
match 'student_account' => 'home#student_account', :via => [:get]
match 'school_account' => 'home#school_account', :via => [:get]
match 'create_account' => 'home#registration_redirect', :via => [:get]
match 'users/create_account' => 'home#registration_entrance', :via => [:get]
match 'registration_redirect' => 'home#registration_redirect', :via=>[:post]
# You can have the root of your site routed with "root"
# just remember to delete public/index.html.
root :to => 'home#home'
get "/auth/oauth2/callback" => "auth0#callback"
get "/auth/verification_complete" => "auth0#verification_complete"
get "/auth/failure" => "auth0#failure"
end
My server log:
Started GET "/ko/lab" for 127.0.0.1 at 2017-09-12 08:58:56 +0300
Processing by ApplicationController#routing_error as HTML
Parameters: {"path"=>"ko/lab"} User Load (202.1ms) SELECT
"users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id"
ASC LIMIT 1 [["id", 12899]] Completed 404 Not Found in 205ms ko/lab
excluded from capture: DSN not set
ActionController::RoutingError (ko/lab):
app/controllers/application_controller.rb:35:in routing_error'
lib/rack/seoredirect.rb:20:incall'
Default local does work but you don't have a route that matches /:locale/lab. Its that simple.
You can create localized routes by using scope - Rails does not do this for you.
scope '(:locale)', locale: /#{I18n.available_locales.join('|')}/ do
get '/' => 'home#home' # this will map /en to home#home
get 'lab' => 'experiments#lab'
# ...
end
This is probably a good time to refactor a really messy routes file by using the resources helper to its full extent:
resources :experiments do
member do
get :info_edit
# ...
end
end
See http://guides.rubyonrails.org/routing.html#adding-more-restful-actions
I have the following two routes in my Rails app:
match '/users/:username' => 'users#show', :via => :get, :as => :user
match '/users(/:filter)' => 'users#index', :via => :get, :as => :users
This is so that I can have routes like:
/users/cameron
/users/popular
Where the first is a user, and the second is a filter.
However the routing in Rails will always hit the first route, because it doesn't know the difference between :username and :filter.
For posts I avoid this problem by doing:
match '/posts/:id' => 'posts#show', :via => :get, :as => :post, :id => /[0-9]/
But this only works because posts are always integers. For example: /posts/21
How can I apply a constraint to my user routes so that they don't trip over each other and without having to add a prefix to either of them.
I've tried this approach (based on the link provided by #Mario
match '/users/:username' => 'users#show', :via => :get, :as => :user, :constraints => lambda { |request| User.usernames.include?(request.params[:username]) }
and in my User model:
def self.usernames
User.pluck(:username)
end
I have an strange issue in my routes file.
This is the part that I need to understand
This routes doesn't work
# V3
# V3 - Home Page
match '/:locale' => 'v3/home#index', :constraints => V3Constraint, :as => :home
# V3 - Search
match '(/:locale)/products/search' => 'v3/products#search', :constraints => V3Constraint
# V3 - Categories index
match '(/:locale)/categories/(:parent_category((/*path)/:category))/(:full)' => 'v3/products#index', :constraints => V3Constraint, :as => :category
# V3 - Prduct Page
match '/:locale/products/:product' => 'v3/products#show', :constraints => V3Constraint, :as => :product
match '(/:locale)/search_amazon' => 'v3/products#search_amazon', :constraints => V3Constraint
# EOF V3
But this work
#V3 - Search
match '(/:locale)/products/search' => 'v3/products#search', :constraints => V3Constraint
# V3 - Categories index
match '(/:locale)/categories/(:parent_category((/*path)/:category))/(:full)' => 'v3/products#index', :constraints => V3Constraint, :as => :category
# V3 - Product Page
match '/:locale/products/:product' => 'v3/products#show', :constraints => V3Constraint, :as => :product
match '(/:locale)/search_amazon' => 'v3/products#search_amazon', :constraints => V3Constraint
# V3 - Home Page
match '/:locale' => 'v3/home#index', :constraints => V3Constraint, :as => :home
If I made the Home Page route have less priority than the others it works, but if it was on the top like the other
this route:
match '(/:locale)/search_amazon' => 'v3/products#search_amazon', :constraints => V3Constraint
will be leading to the home page.
Can any please explain why this is has to happen ?
Thanks.
Having a route like this <yourdomain>/search_amazon will match the first one of these two routes
match '(/:locale)/search_amazon' => 'v3/products#search_amazon', :constraints => V3Constraint
In this case, it will match because locale is optional here.
match '/:locale' => 'v3/home#index', :constraints => V3Constraint, :as => :home
While here it will match making search_amazon as the value for locale.
I'm trying to have different paths for the same devise model/resource with constraints, but the first path is the one being applied in this case "visitor".
constraints(ValidSubdomainFrontend) do
devise_for :users, :path => "visitor", :path_names => { :sign_in => 'login', :sign_out => 'logout', :password => 'secret', :confirmation => 'verification', :unlock => 'unblock', :registration => 'register', :sign_up => 'cmon_let_me_in' }
end
constraints(ValidSubdomainAdmin) do
devise_for :users do
get 'users', :path => "admin", :to => 'site_backend#index', :as => :user_root # Rails 3
end
devise_for :users, :controllers => { :registrations => 'users' }, :path => "admin", :path_names => { :sign_in => 'login', :sign_out => 'logout', :password => 'secret', :confirmation => 'verification', :unlock => 'unblock', :registration => 'register', :sign_up => 'cmon_let_me_in' }
end
Is it possible to have different paths for the same resource with Devise on different constraints?
The constraints being used are:
class ValidSubdomainAdmin
def self.matches?(request)
request.subdomain.present? &&
request.env['PATH_INFO'].start_with?('/admin')
end
end
class ValidSubdomainFrontend
def self.matches?(request)
request.subdomain.present? &&
!request.env['PATH_INFO'].start_with?('/admin')
end
end
Is this possible with Devise at all or is this a Bug?
Found the solution for this issue!
More on the context, basically needed to have something like /visitor on the front-end where users can login (to the members area) and edit their profile and other members/clients operations. But I would also want /admin where admins/editors/authors can login to the (backend) admin dashboard/area. Both areas use the same Devise model/resource (so an admin can also visit the members area). As a side note, currently I'm using CanCan permissions to prevent members from accessing the admin area.
I just had to replace the admin area constraint for:
constraints(ValidSubdomainAdmin) do
devise_scope :user do
#root :to => "devise/registrations#new"
get "admin/" => "admin#index"
post 'admin/' => 'devise/registrations#new', :as => :new_admin_registration
match 'admin/', :to => 'admin#index'
get "admin/edit" => "devise/registrations#edit"
match 'admin/edit', :to => 'devise/registrations#edit'
get "admin/login" => "devise/sessions#new", :as => :new_admin_session
match 'admin/login', :to => 'devise/sessions#new'
get "admin/logout" => "devise/sessions#destroy", :as => 'destroy_admin_session'
match 'admin/logout', :to => 'devise/sessions#destroy'
post "admin/password" => "devise/passwords#create"
get "admin/password/new" => "devise/passwords#new", :as => 'new_admin_password'
get "admin/password/edit" => "devise/passwords#edit"
put "admin/password" => "devise/passwords#update"
end
end
I also updated the views /admin/users (being used by devise on the on the admin area) to use the new admin devise paths.
Many thanks to José Valim
I have the following routes
match 'tracks/:id/entire_graph'=> "tracks#entire_graph", :as => "entire_graph"
match 'tracks/:id/entire_graph/:rid'=> "tracks#entire_graph", :as => "entire_graph2"
match 'tracks/:id/:rid' => "tracks#blahh", :as => "refer_your_friends"
resources :tracks
match '/auth/:provider/callback' => 'authentications#create'
match '/auth/failure' => 'authentications#failure'
match '/tracks/:id/:rid/facebookpost' => 'tracks#facebook_post', :as => "facebook_post_track"
match '/tracks/:id/:rid/twitterpost' => 'tracks#twitter_post', :as => "twitter_post_track"
resources :authentications
My problem is regarding the 'tracks/:id/:rid' route.
I am trying to call it like this: 'tracks/9/15'
I get a value for params[:id], but params[:rid] = nil, and I cannot figure out why.