Rails 3.1命名路由从演示者查询params问题

时间:2012-09-27 22:56:23

标签: ruby-on-rails ruby-on-rails-3.1

将应用程序从Rails 3.0.17升级到3.1.8后,我遇到了一个奇怪的错误,即使用命名路由并添加查询参数。

向后开始,这是相关的错误和堆栈跟踪:

NameError (undefined local variable or method `env' for #<AnswerPagesPresenter:0x0000000420df60>):
  actionpack (3.1.8) lib/action_controller/metal/url_for.rb:36:in `url_options'
  actionpack (3.1.8) lib/action_dispatch/routing/url_for.rb:148:in `url_for'
  actionpack (3.1.8) lib/action_dispatch/routing/route_set.rb:207:in `edit_answer_sheet_page_path'
  vendor/plugins/questionnaire_engine/app/presenters/answer_pages_presenter.rb:81:in `new_page_link'
  vendor/plugins/questionnaire_engine/app/presenters/answer_pages_presenter.rb:91:in `block (2 levels) in page_list'
  vendor/plugins/questionnaire_engine/app/presenters/answer_pages_presenter.rb:90:in `each'
  vendor/plugins/questionnaire_engine/app/presenters/answer_pages_presenter.rb:90:in `block in page_list'
  vendor/plugins/questionnaire_engine/app/presenters/answer_pages_presenter.rb:89:in `each'
  vendor/plugins/questionnaire_engine/app/presenters/answer_pages_presenter.rb:89:in `page_list'
  vendor/plugins/questionnaire_engine/app/presenters/answer_pages_presenter.rb:21:in `initialize'
  app/controllers/applications_controller.rb:166:in `new'
  app/controllers/applications_controller.rb:166:in `setup_view'
  app/controllers/applications_controller.rb:19:in `show_default'
...

这是AnswerPagesPresenter中调用命名路由的一段代码(我尝试使用多个东西作为'a'变量,这是额外的查询参数,但它通常是零):

def new_page_link(answer_sheet, page, a = nil)
  PageLink.new(page.label, edit_answer_sheet_page_path(answer_sheet, page, :a => a), dom_page(answer_sheet, page), page) if page
end

同样在我的Presenter类的顶部,我有以下几行代码:

include ActionView::Helpers::TagHelper # link_to
include ActionView::Helpers::UrlHelper # url_for
include ActionController::UrlFor # named routes
include ActionController::RecordIdentifier # dom_id
include Rails.application.routes.url_helpers

运行'rake routes'命令的相关行只是为了表明它是一条有效路线:

edit_answer_sheet_page GET    /answer_sheets/:answer_sheet_id/page/:id/edit(.:format)     {:action=>"edit", :controller=>"answer_pages"}

来自插件中的routes.rb文件:

resources :answer_sheets do 
  member do
    post :send_reference_invite
    post :submit
  end
  resources :page, :controller => :answer_pages do
    member do
      post :save_file
    end
  end
end                 

任何人都知道这里发生了什么?我试图弄清楚为什么它会转到lib / action_controller / metal / url_for.rb而不是仅仅使用lib / action_dispatch / routing / url_for.rb中的url_options方法,但是当涉及到Rails时我很无能为力源代码。这在Rails 3.0.17中运行得很好。我很欣赏任何见解!

1 个答案:

答案 0 :(得分:0)

在查看此提交https://github.com/rails/rails/commit/233be6572c96087192885924c6658a15d01a2a1b#actionpack/lib/action_controller/metal/url_for.rb

后,我发现了问题所在

显然,如果你从一个控制器调用一个命名路由,你会没事的,因为已经定义了env。但是如果你从别的东西中调用它,env就没有定义,你必须自己定义它。因为它是从一个自编的演示者(包含对控制器的引用)调用的,所以我只是在Presenter(AnswerPagesPresenter的超类)中编写了以下方法,它现在可以工作了:

def env
  @controller.env
end