【问题标题】:rails I18n wrong parameter order in route (id as locale and id is nil)rails I18n 路由中的参数顺序错误(id 作为语言环境,id 为 nil)
【发布时间】:2015-04-29 14:09:08
【问题描述】:

我想用 i18n 为 rails 国际化一个外部代码(参见github)。我已经阅读了Rails Internationalization (I18n) API 的指南。翻译文本不是问题,但底层代码似乎无法在所有情况下正常工作。不幸的是,我不是 rails/ruby 专家。

来自日志:

FATAL -- : ActionView::Template::Error (没有路由匹配 {:action=>"edit", :controller=>"plans", :format=>nil, :id=>nil, :locale=>115} 缺少必需的键:[: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 上找到(抱歉,我无法发布链接,因为我没有足够的声誉)。 任何建议/帮助都是完美的。

编辑 我想我离得更近了一点。也许现在更清楚了,为什么它不起作用。 首先是“完整”堆栈跟踪:

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'

如果我点击网页上的“完成”按钮,就会调用函数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_urledit_user_url。因为如果我添加一些随机文本作为参数,它就可以工作......:

edit_plan_url("de",@vars[:plan])
and in _notification:
edit_user_url("de",@vars[:user].id)

问题是,它为什么有效?有没有办法打印创建的路线?因为在堆栈跟踪中路由不匹配,因为格式和 id 为 nil。现在我想查看新路由,以了解我的随机字符串“de”的放置位置。

【问题讨论】:

  • 从您的路线中删除locale: /en|de/,然后重试。
  • @sadaf2605 不幸的是这没有效果,我仍然得到错误。
  • 粘贴创建请求的表单。看起来你传递了错误的参数。
  • @JorgedelosSantos with byebug 我可以把它缩小到这个命令:plan_state = PlanState.create( plan_id: @plan.id, state: state, user_id: current_user.id)
  • 问题出在参数中,(没有路由匹配 {:action=>"edit", :controller=>"plans", :format=>nil, :id=>nil, :locale => 115})。您的表单将 id 作为 nil 发送,将语言环境作为 id 发送。您需要粘贴表单代码。

标签: ruby-on-rails ruby rails-i18n i18n-gem


【解决方案1】:

看起来您的路线需要两个参数,并在它出现时对其进行排序。有一种方法可以通过在传递的参数中使用命名散列来避免它:

edit_plan_url(id: @vars[:plan].id)

Rails Automagic 将使用符号来识别参数并避免问题。

【讨论】:

  • 关于将 I18n.locale 放入调用中:这是一个选项,但问题是,为什么这是必要的。因为我认为任务是在 default_url_options 中完成的(在 application_controller 内)。这适用于许多情况。我这样做的问题是,我不知道完整的代码。如果我为这两种情况解决这个问题,可能还有十个,我不知道。因此我认为,I18n 通过 default_url_options 以一般方式执行此操作。
  • 你为什么使用:edit_plan_url而不是edit_plan_path?您是否重命名了路线?
  • 这不是我的代码。我没有对这段代码进行任何更改,所以我不知道为什么使用edit_plan_url而不是edit_plan_path。我认为使用了 edit_plan_url,因为链接是通过邮件发送的。我的目标是使用该代码,但要“实现”国际化。我们想使用这个开源工具,但使用不同的语言。如果我完成了国际化,我将为作者提供“新功能”。
  • 但是你能用 _path 改变 _url 吗?有用吗?
  • 不幸的是它不起作用(我只是打电话给rake assets:precompile,我希望这已经足够了)。如果我只使用edit_plan_path(@vars[:plan]),那么我会得到相同的无路由匹配错误。如果我添加 edit_plan_path("xy",@vars[:plan]) 我不会收到错误消息。
猜你喜欢
  • 1970-01-01
  • 2018-06-02
  • 2016-08-25
  • 1970-01-01
  • 2012-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多