发布/置位请求的路由错误(乘客标头)

时间:2013-01-02 02:15:02

标签: ruby-on-rails passenger

我遇到了一个奇怪的问题,经过一系列的研究无法接近。我有几种通过Carrierwave上传文件的表单。当我上传信息时,部分路线被切断(我认为)。

例如,我有一个多部分表单提交到:

  

https:/ domain / programs / 223 / add_file as POST

但在提交时我收到错误

  

没有路线匹配[POST]“/ 223 / add_file”

即使我的地址栏中的内容是完整的路线。如果将完整路线作为GET请求提交,则可以正常工作。当我运行rake路线时,路线显示就好了。

以下是我路线的一部分:

resources :programs do
  match "add_file" => "programs#add_file"

如果重要的话,我在Apache上使用Passenger运行Rails 3.2.2。问题只发生在这个生产服务器上,从不在开发中。

有什么想法吗?我坚持这个,因为它影响多个路线,我已经尝试为那个形式定义一个没有运气的自定义路线。

更新 当我删除多部分=> true或表单中的file_field_tag修复了问题。它仍然是一个问题,但似乎不是关于路由而是关于文件上传的表单。

3 个答案:

答案 0 :(得分:6)

使用以下代码在passenger_extension.rb文件夹中创建lib

乘客3

module PhusionPassenger
  module Utils

    protected

    NULL = "\0".freeze

    def split_by_null_into_hash(data)
      args = data.split(NULL, -1)
      args.pop
      headers_hash = Hash.new
      args.each_slice(2).to_a.each do |pair|
        headers_hash[pair.first] = pair.last unless headers_hash.keys.include? pair.first
      end
      return headers_hash
    end

  end
end

乘客5

module PhusionPassenger
  module Utils

    # Utility functions that can potentially be accelerated by native_support functions.
    module NativeSupportUtils
      extend self

      NULL = "\0".freeze

      class ProcessTimes < Struct.new(:utime, :stime)
      end

      def split_by_null_into_hash(data)
        args = data.split(NULL, -1)
        args.pop
        headers_hash = Hash.new
        args.each_slice(2).to_a.each do |pair|
          headers_hash[pair.first] = pair.last unless headers_hash.keys.include? pair.first
        end
        return headers_hash
      end

      def process_times
        times = Process.times
        return ProcessTimes.new((times.utime * 1_000_000).to_i,
          (times.stime * 1_000_000).to_i)
      end
    end

  end # module Utils
end # module PhusionPassenger

然后在'config / application.rb'中执行:

class Application < Rails::Application
  ...
  config.autoload_paths += %W(#{config.root}/lib)
  require 'passenger_extension'
end

然后重新启动网络服务器。

注意:我不确定这是否会破坏任何其他功能,因此请自行承担风险,如果您发现此方法有任何损害,请与我们联系。

答案 1 :(得分:0)

这里的一个问题是您没有指定路由是在集合上还是在成员上定义的。哪一个是正确的路线?

programs/:id/add_file

programs/add_file

你应该像这样构建你的路线:

resources :programs do
  post 'add_file', :on => :member
end

resources :programs do
  member do
    post 'add_file'
  end
end

上述内容将在programs/:id/add_file上发布请求,并将ProgramsController.add_file作为程序ID发送给params[:id]

如果你想在集合中使用它,你可以这样做:

resources :programs do
  post 'add_file', :on => :collection
end

resources :programs do
  collection do
    post 'add_file'
  end
end

这会在programs/add_file上发布请求并将其发送到ProgramsController.add_file,但不会设置params[:id]

一般情况下,您应始终指定路线是否在集合或成员上,并且您应指定路线应接受的动词(即使用'get'或'post'等而不是'match')。

尝试以上操作,看看是否能解决您的问题,如果没有,请告诉我,我会再看看。

答案 2 :(得分:0)

我认为您可能需要添加

:via => [:post]

到你的路线规范。看起来它很适合开发而不是生产,但是当我理解rails路由时,你添加的匹配器只会响应get。

尝试将您的匹配更改为

match "add_file" => "programs#add_file", :via => [:post]

另外,根据Andrew刚刚提交的答案,您最好使用成员说明符明确表示操作是在具有特定ID的特定程序上发生的,而不是集合。它还应该在你的add_file方法中保存一些代码,这可能很难从url获取id参数。