Why default locale does not work? - ruby-on-rails

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

Related

Class level method "undefined"

With the code below:
class TestController < ApplicationController
wrap_parameters :test, format: [:json, :xml], include: self.test_method
def self.test_method
[ :one, :two, :three ]
end
end
I get a RoutingError:
ActionController::RoutingError (undefined method 'test_method' for TestController:Class)
I tried a number of different derivations of this, but nothing is working.
EDIT: routes.rb -- was routing to api.servername/create during error:
TestApp::Application.routes.draw do
resources :subscriptions
# API subdomain
constraints subdomain: 'api' do
get '/' => 'test#index'
post '/create', to: 'test#create'
get '/status', to: 'test#show'
end
# root route
root to: 'pages#index'
# User routes
devise_scope :user do
get 'login' => 'devise/sessions#new', :as => :new_user_session
post 'login' => 'devise/sessions#create', :as => :user_session
delete 'logout' => 'devise/sessions#destroy', :as => :destroy_user_session
get 'register' => 'devise/registrations#new', :as => :new_user_registration
get 'profile' => 'devise/registrations#edit', :as => :edit_user_registration
get 'users' => 'users/registrations#index'
end
devise_for :users, :skip => [:sessions], controllers: { registrations: 'users/registrations' }
end

Rails routes with optional parameters priorities

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.

How to use same route path for both locales

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

Rails 4: Invalid route name, already in use (ArgumentError)

Well the error is telling the truth, I have used the route name 'contact' twice, but one match is for a get request and the other for a post. I have been following the following tutorial for setting up Contact Form in Rails: http://matharvard.ca/posts/2011/aug/22/contact-form-in-rails-3/, and the author suggests adding the following to my routes file:
match 'contact' => 'contact#new', :as => 'contact', :via => :get
match 'contact' => 'contact#create', :as => 'contact', :via => :post
However that gives me the following error:
Invalid route name, already in use: 'contact' (ArgumentError)
Here is my own routes.rb file:
Fls::Application.routes.draw do
root 'welcome#index'
match 'contact' => 'contact#new', :via => :get
match 'contact' => 'contact#create', :as => 'contact', :via => :post
end
Do the following instead of above:
resource :contact, only: [:new, :create]
OR
get 'contact' => 'contact#new'
post 'contact' => 'contact#create', :as => 'contact'

Devise custom routes slippery slope

I started using custom routes w/Devise so that I could have my 'Sign In' and 'Sign Up' routes go to the same page. However, as soon as I followed the instruction from Devise about custom routes, it seems that every route now has to be explicitly specified. This has now broken my reset password links since that portion is handled by Devise.
What am I doing wrong here? You can see below that I've had to spell out everything for my User and UserSessions model. Shouldn't I only have to specify the ones I want to change?
devise_for :users, :controllers => { :sessions => "user_sessions" ,:registrations=>"users"},:skip => [:sessions] do
get 'users/sign_in' => 'user_sessions#new', :as => :new_user_session
get 'users/sign_up' => 'user_sessions#new', :as => :new_user_session
post 'users/sign_in' => 'user_sessions#create', :as => :user_session
post 'user_sessions' => 'user_sessions#create', :as => :app_sign_in
delete 'users/sign_out' => 'user_sessions#destroy', :as => :destroy_user_session
get 'users/sign_out' => 'user_sessions#destroy', :as => :destroy_user_session
post 'users/:id' => 'users#update', :as =>:update_user
get 'users' => 'users#index'
get 'users/:id/edit' => 'users#edit', :as => :edit_user
get 'users/:id' => 'users#show', :as => :show_user
delete 'users/:id' => 'users#destroy', :as => :destroy_user
end
Can you just use, not sure if this will work for you
devise_for :users
devise_for :users do
get '/users/sign_out' => 'devise/sessions#destroy'
end

Resources