Starting rails I18n and url helpers seem to confus

2019-08-01 05:11发布

I have just started trying to update our rails 3.2 app for internationalization. I have an optional scope in the routes, like

scope "(:locale)", locale: /en|es|zh-HK|de|fr/ do

as described by http://guides.rubyonrails.org/i18n.html.

And my url helper like

watch_url(@watch)

gets errors in the form

No route matches {:action=>"show", :controller=>"watches", :locale=>#<Watch id: 1, rule_name: "MyRule", start_time: "2014-06-08 03:30:03", end_time: nil, last_execution_time: nil, frequency_mins: 60, rest_period: 0, enabled: true, last_rule_result: false, owner: "me", one_shot: false, args: {"x"=>"", "recipients"=>"", "attributes"=>""}, state: {}, hidden: false, comment: "">}

Any ideas on why it is happening and how I can fix it?

Thanks!

EDIT:

In my application controller, I have

  before_filter :set_locale

  def set_locale
    I18n.locale = params[:locale] || I18n.default_locale
  end

And the routes that are for the watches controller (This is an 8 year old proprietary app and we have 100+ controllers :(, so I won't include all the routes)...

$ rake routes | grep watch
                              watches GET    (/:locale)/watches(.:format)                                                         watches#index  {:locale=>/en|es|zh-HK|de|fr/}
                                      POST   (/:locale)/watches(.:format)                                                         watches#create {:locale=>/en|es|zh-HK|de|fr/}
                            new_watch GET    (/:locale)/watches/new(.:format)                                                     watches#new {:locale=>/en|es|zh-HK|de|fr/}
                           edit_watch GET    (/:locale)/watches/:id/edit(.:format)                                                watches#edit {:locale=>/en|es|zh-HK|de|fr/}
                                watch GET    (/:locale)/watches/:id(.:format)                                                     watches#show {:locale=>/en|es|zh-HK|de|fr/}
                                      PUT    (/:locale)/watches/:id(.:format)                                                     watches#update {:locale=>/en|es|zh-HK|de|fr/}
                                      DELETE (/:locale)/watches/:id(.:format)                                                     watches#destroy {:locale=>/en|es|zh-HK|de|fr/}

I don't think the show method is relevant. The error happens in the url helper, and the flow never gets to the show code.

1条回答
叛逆
2楼-- · 2019-08-01 06:13

You need to give the url helper a locale option as well in order for it to be passed through correctly:

watch_url(@watch, locale: I18n.locale)

If that's a bit annoying, you can override the Rails url_options method to always give every request a :locale option so you never ended up having to specify it in any of your views (some guides, including the Rails guides link above, say to override the default_url_options method, but that didn't work for me...):

app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  # Every helper method dependent on url_for (e.g. helpers for named
  # routes like root_path or root_url, resource routes like books_path
  # or books_url, etc.) will now automatically include the locale in
  # the query string,
  def url_options
    { locale: I18n.locale }.merge(super)
  end

  # ...
end

app/views/your_view

# locale not needed explicitly as it's set in the controller
<%= link_to watch_url(@watch) %>
查看更多
登录 后发表回答