5

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

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

https:/domain/programs/223/add_file 作为 POST

但在提交时我收到错误

没有路由匹配 [POST] "/223/add_file"

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

这是我的路线的一个子集:

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

如果重要的话,我在 Apache 上运行 Rails 3.2.2 和Passenger。该问题仅发生在此生产服务器上,从未在开发中。

有任何想法吗?我被困在这个上,因为它影响了多条路线,我已经尝试为该表格定义一个自定义路线,但没有运气。

更新: 当我从表单中删除 multi-part => true 或 file_field_tag 时,它可以解决问题。这仍然是一个问题,但似乎与其说是关于路由,不如说是关于带有文件上传的表单。

4

3 回答 3

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

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

注意:我不确定这不会破坏任何其他功能,因此使用它需要您自担风险,如果您发现这种方法有任何危害,请告诉我。

于 2013-03-08T11:48:15.443 回答
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

上面将接受 post 请求programs/:id/add_file并将它们作为程序 id发送ProgramsController.add_file到。params[:id]

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

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

或者

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

这将接受 post 请求programs/add_file并将它们发送到ProgramsController.add_file,但不会params[:id]设置。

一般来说,您应该始终指定路由是否在集合或成员上,并且您应该指定路由应该接受哪个动词(即使用'get'或'post'等而不是'match')。

试试上面的方法,看看能不能解决你的问题,如果不能,请告诉我,我再看看。

于 2013-01-02T02:29:03.647 回答
0

我认为您可能需要添加

:via => [:post]

根据您的路线规范。它适用于开发而不是生产似乎很奇怪,但据我了解 Rails 路由,您添加的匹配器只会响应获取。

尝试将匹配更改为

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

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

于 2013-01-02T02:35:04.633 回答