rails I18n 路由中的参数顺序错误(id 为语言环境且 id 为 nil)
rails I18n wrong parameter order in route (id as locale and id is nil)
我想国际化外部代码(参见 github) with i18n for rails. I have read the guide for Rails Internationalization (I18n) API。翻译文本不是问题,但底层代码似乎无法在所有情况下正常工作。不幸的是,我不是 rails/ruby专家.
来自日志:
FATAL -- : ActionView::Template::Error (No route matches
{:action=>"edit", :controller=>"plans", :format=>nil, :id=>nil,
:locale=>115} missing required keys: [:id]):
所以问题是,id (=115) 的参数作为区域设置而不是 id 传递。
为了使 i18n 正常工作,我将以下代码添加到 app/controllers/application_controller.rb:
...
before_action :set_locale
protected
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
end
def default_url_options(options = {})
{ locale: I18n.locale }.merge options
end
...
此外,我将原始路由包装在 config/routes.rb:
Dmptool2::Application.routes.draw do
scope "(:locale)", locale: /en|de/ do
a lot of original routes
end
end
因此,问题是,是否缺少路由或代码内部有问题,还是只是我的错。除了翻译文本和按钮外,我没有更改原始代码。原来的 routes.rb 可以在 github 上找到(对不起,我不能 post 和 link 因为我没有足够的声誉)。
任何建议/帮助都是完美的。
编辑
我觉得我更接近一点。也许现在更清楚了,为什么它不起作用。
首先是 "full" 堆栈跟踪:
F, [2015-05-04T16:43:58.600384 #19289] FATAL -- :
ActionView::Template::Error (No route matches {:action=>"edit", :controller=>"plans", :format=>nil, :id=>nil, :locale=>#<Plan id: 158, name: "asdfe", requirements_template_id: 59, solicitation_identifier: "",
submission_deadline: nil, visibility: :public, created_at: "2015-05-04 14:41:33", updated_at: "2015-05-04 14:43:48", current_plan_state_id: 300>} missing required keys: [:id]):
2:
3: The plan "<%= @vars[:plan].name %>" has been completed.
4:
5: If you have questions pertaining to this action, please visit the DMP Overview page at <%= edit_plan_url(@vars[:plan]) %>
6:
7: <%= render :partial => 'users_mailer/notification_boilerplate.text.erb' %>
app/views/users_mailer/dmp_owners_and_co_committed.text.erb:5:in `_app_views_users_mailer_dmp_owners_and_co_committed_text_erb__754483862330985648_69917281861000'
app/mailers/users_mailer.rb:32:in `notification'
app/models/concerns/plan_email.rb:50:in `block in email_dmp_saved'
app/models/concerns/plan_email.rb:49:in `email_dmp_saved'
app/models/plan_state.rb:31:in `update_current_plan_state'
app/controllers/plan_states_controller.rb:97:in `create_plan_state'
app/controllers/plan_states_controller.rb:73:in `committed'
如果我点击网页上的 "done" 按钮,将调用函数 committed
,即调用 create_plan_state(:committed)
。在 create_plan_state 的定义中,有语句 plan_state = PlanState.create( plan_id: @plan.id, state: state, user_id: current_user.id)
。这会触发 after_create: update_current_plan_state
:
的回调
def update_current_plan_state
#update the current plan pointer in the plan model
p = self.plan
p.current_plan_state_id = self.id
p.save!
end
现在,这会触发 after_save: email_dmp_saved
:
def email_dmp_saved
...
if current_state.state == :committed
users = self.users
users.delete_if {|u| !u[:prefs][:dmp_owners_and_co][:committed]}
users.each do |user|
UsersMailer.notification(
user.email,
"PLAN COMPLETED: #{self.name}",
"dmp_owners_and_co_committed",
{:user => user, :plan => self } ).deliver
end
我认为通知的定义并不重要。但倒数第 3 行调用 "dmp_owners_and_co_committed",其定义为:
Hello <%= @vars[:user].full_name %>,
The plan "<%= @vars[:plan].name %>" has been completed.
If you have questions pertaining to this action, please visit the DMP Overview page at <%= edit_plan_url(@vars[:plan]) %>
<%= render :partial => 'users_mailer/notification_boilerplate.text.erb' %>
在_notification_boilerplate.text.erb中有:
You may change your notification preferences at <%= edit_user_url(@vars[:user].id) %>#tab_tab2 .
我认为问题是 edit_plan_url
和 edit_user_url
。因为如果我添加一些随机文本作为参数它会起作用...:[=28=]
edit_plan_url("de",@vars[:plan])
and in _notification:
edit_user_url("de",@vars[:user].id)
问题是,它为什么有效?有没有办法打印创建的路线?因为在堆栈跟踪中,路由不匹配,因为 format 和 id 为 nil。现在我想查看新路线,以便知道我的随机字符串 "de" 放在哪里。
看起来你的路线需要两个参数,并在它出现时对其进行排序。有一种方法可以通过在传递的参数中使用命名哈希来避免它:
edit_plan_url(id: @vars[:plan].id)
Rails Automagic 将使用符号来识别参数并避免问题。
我想国际化外部代码(参见 github) with i18n for rails. I have read the guide for Rails Internationalization (I18n) API。翻译文本不是问题,但底层代码似乎无法在所有情况下正常工作。不幸的是,我不是 rails/ruby专家.
来自日志:
FATAL -- : ActionView::Template::Error (No route matches {:action=>"edit", :controller=>"plans", :format=>nil, :id=>nil, :locale=>115} missing required keys: [:id]):
所以问题是,id (=115) 的参数作为区域设置而不是 id 传递。
为了使 i18n 正常工作,我将以下代码添加到 app/controllers/application_controller.rb:
...
before_action :set_locale
protected
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
end
def default_url_options(options = {})
{ locale: I18n.locale }.merge options
end
...
此外,我将原始路由包装在 config/routes.rb:
Dmptool2::Application.routes.draw do
scope "(:locale)", locale: /en|de/ do
a lot of original routes
end
end
因此,问题是,是否缺少路由或代码内部有问题,还是只是我的错。除了翻译文本和按钮外,我没有更改原始代码。原来的 routes.rb 可以在 github 上找到(对不起,我不能 post 和 link 因为我没有足够的声誉)。 任何建议/帮助都是完美的。
编辑 我觉得我更接近一点。也许现在更清楚了,为什么它不起作用。 首先是 "full" 堆栈跟踪:
F, [2015-05-04T16:43:58.600384 #19289] FATAL -- :
ActionView::Template::Error (No route matches {:action=>"edit", :controller=>"plans", :format=>nil, :id=>nil, :locale=>#<Plan id: 158, name: "asdfe", requirements_template_id: 59, solicitation_identifier: "",
submission_deadline: nil, visibility: :public, created_at: "2015-05-04 14:41:33", updated_at: "2015-05-04 14:43:48", current_plan_state_id: 300>} missing required keys: [:id]):
2:
3: The plan "<%= @vars[:plan].name %>" has been completed.
4:
5: If you have questions pertaining to this action, please visit the DMP Overview page at <%= edit_plan_url(@vars[:plan]) %>
6:
7: <%= render :partial => 'users_mailer/notification_boilerplate.text.erb' %>
app/views/users_mailer/dmp_owners_and_co_committed.text.erb:5:in `_app_views_users_mailer_dmp_owners_and_co_committed_text_erb__754483862330985648_69917281861000'
app/mailers/users_mailer.rb:32:in `notification'
app/models/concerns/plan_email.rb:50:in `block in email_dmp_saved'
app/models/concerns/plan_email.rb:49:in `email_dmp_saved'
app/models/plan_state.rb:31:in `update_current_plan_state'
app/controllers/plan_states_controller.rb:97:in `create_plan_state'
app/controllers/plan_states_controller.rb:73:in `committed'
如果我点击网页上的 "done" 按钮,将调用函数 committed
,即调用 create_plan_state(:committed)
。在 create_plan_state 的定义中,有语句 plan_state = PlanState.create( plan_id: @plan.id, state: state, user_id: current_user.id)
。这会触发 after_create: update_current_plan_state
:
def update_current_plan_state
#update the current plan pointer in the plan model
p = self.plan
p.current_plan_state_id = self.id
p.save!
end
现在,这会触发 after_save: email_dmp_saved
:
def email_dmp_saved
...
if current_state.state == :committed
users = self.users
users.delete_if {|u| !u[:prefs][:dmp_owners_and_co][:committed]}
users.each do |user|
UsersMailer.notification(
user.email,
"PLAN COMPLETED: #{self.name}",
"dmp_owners_and_co_committed",
{:user => user, :plan => self } ).deliver
end
我认为通知的定义并不重要。但倒数第 3 行调用 "dmp_owners_and_co_committed",其定义为:
Hello <%= @vars[:user].full_name %>,
The plan "<%= @vars[:plan].name %>" has been completed.
If you have questions pertaining to this action, please visit the DMP Overview page at <%= edit_plan_url(@vars[:plan]) %>
<%= render :partial => 'users_mailer/notification_boilerplate.text.erb' %>
在_notification_boilerplate.text.erb中有:
You may change your notification preferences at <%= edit_user_url(@vars[:user].id) %>#tab_tab2 .
我认为问题是 edit_plan_url
和 edit_user_url
。因为如果我添加一些随机文本作为参数它会起作用...:[=28=]
edit_plan_url("de",@vars[:plan])
and in _notification:
edit_user_url("de",@vars[:user].id)
问题是,它为什么有效?有没有办法打印创建的路线?因为在堆栈跟踪中,路由不匹配,因为 format 和 id 为 nil。现在我想查看新路线,以便知道我的随机字符串 "de" 放在哪里。
看起来你的路线需要两个参数,并在它出现时对其进行排序。有一种方法可以通过在传递的参数中使用命名哈希来避免它:
edit_plan_url(id: @vars[:plan].id)
Rails Automagic 将使用符号来识别参数并避免问题。