问题
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
回答1:
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
回答2:
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
来源:https://stackoverflow.com/questions/10052158/why-rails-app-is-redirecting-unexpectedly-instead-of-matching-the-route