Rails Rails upload file error about “No such file or directory @ rb_sysopen”

runup · June 28, 2017 · Last by runup replied at June 28, 2017 · 4433 hits

参考 rails5 的 guides,下面的代码出现 Rails upload file error about“No such file or directory @ rb_sysopen,/Users/jayzen/workshop/upload_demo/public/uploads/demo.pdf”。

def upload
  uploaded_io = params[:tag][:attachment]
  File.open(Rails.root.join('public', 'uploads', uploaded_io.original_filename), 'wb') do |file|
  file.write(uploaded_io.read)
end

我对代码中 Rails.root.join 的参数个数做了修改,只是去掉“uploads”参数,代码如下,下面的代码按照预期运行,并且上传文件成功。

def upload
  uploaded_io = params[:tag][:attachment]
  File.open(Rails.root.join('public', uploaded_io.original_filename), 'wb') do |file|
  file.write(uploaded_io.read)
end

问题:当 Rails.root.join 中的参数个数小于等于 2 时候,能够正常运行,但是参数个数大于 2 时,则会出现如上的问题,为何?

其他辅助代码

#支架 
rails g scaffold tag name

#model中设置虚拟属性
class Tag < ActiveRecord
  attr_accessor :attachment
end

#controller中设置attachment白名单
params.require(:tag).permit(:name, :attachment)

#controller中添加upload方法
class TagsController < ApplicationController
  def create
    @tag = Tag.new(tag_params)
    if @tag.save
      upload
     ......
  end

  private
    def upload
    ....
    end
end

环境:mac, ruby2.4.0, rails5.1.2

你确定 uploads 存在于那个路径?

Reply to jasl

不太懂您说的

Reply to runup

就是 public/uploads 目录存在?

Reply to jasl

懂了,首先创建文件夹,才能在文件夹下面新建文件。

问题解决: 原本打算将 pdf 文件存储在对应 id 目录的文件下面,代码如下所示

def upload
  uploaded_io = params[:tag][:attachment]
  File.open(Rails.root.join('public','uploads', "#{@tag.id}", uploaded_io.original_filename), 'wb') do |file|
    file.write(uploaded_io.read)
  end
end

报如上提到的错误,按照楼上的提示,添加新建文件夹语句,修改后的代码如下

def upload
  uploaded_io = params[:tag][:attachment]
  demo = Dir.mkdir(File.join(Rails.root, 'public', 'uploads', "#{@tag.id}"))
  File.open(Rails.root.join('public','uploads', "#{@tag.id}", uploaded_io.original_filename), 'wb') do |file|
    file.write(uploaded_io.read)
  end
end

runup closed this topic. 28 Jun 23:26
You need to Sign in before reply, if you don't have an account, please Sign up first.