lundi 8 janvier 2018

Permission denied @ unlink_internal, Rails 5 with CarrierWave

I have Ruby on Rails 5 with CarrierWave application. I have a model Post and a model 'Image'. Each post has only 1 video (it has column video in the table posts) and 0 or many images (table images). Model Post:

has_many :images

validates :video, presence: true
validates_associated :images

mount_uploader :video, VideoUploader

Model Image:

belongs_to :post
mount_uploader :image, ImageUploader

The video is required, but the images are not.

ImageUploader:

storage :file

def store_dir
  "posts/images"
end

def extension_whitelist
  %w(jpeg jpg)
end

def filename
  "#{secure_token}.jpg" if original_filename.present?
end

def remove_original_file(p)
  if self.version_name.nil?
    self.file.delete if self.file.exists?
  end
end
# GENERATE RANDOM NAME
def secure_token
  var = :"@#{mounted_as}_secure_token"
  model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.uuid)
end

VideoUploader:

storage :file

def store_dir
  "../videos/#{model.id}" # Not in the public directory
end

def extension_whitelist
  %w(mp4)
end

def filename
  "#{secure_token}.mp4" if original_filename.present?
end

# GENERATE RANDOM NAME
def secure_token
  var = :"@#{mounted_as}_secure_token"
  model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.uuid)
end

This a part of the view for form upload:

<%= form_for @post do |f| %>
.....
<%= f.fields_for :images do |i| %>
  <%= i.file_field :image, name: 'post[images_attributes][][image]' %>
  ......
  <%= i.file_field :image, name: 'post[images_attributes][][image]' %>
<% end %>

The input element for a video:

 <%=f.file_field :video, required: false, accept: '.mp4'%>

This posts_controller.rb:

def new
  @post= Performance.new
  @post.images.build
end

def create
  @post= Post.new(post_params)

  if @post.save 
    redirect_to action: :new
  else
    @post.images.build if @post.images.size == 0
    render :new
  end
end

private
def post_params
  params.require(:post).permit(:language, :name, :video, :slug, 
                                        :images_attributes => [:image])
end

There is no problem if I upload a post with 1 image. Everything works fine. The files (an image and a video) are uploaded and all data is in the database. The problem is when I try to upload more than 1 image. I see this error:

Permission denied @ unlink_internal - E:/project pah/public/uploads/tmp/1515418372-4328-0043-1599/video.mp4

I am using Windows 10. All the folders (public/*) are with all permissions (except special permissions) for all users.

The problem exists ONLY if I upload more than 1 image, but in some kind, it is related to the video.

After trying to upload and getting the error, I see that the temporary directory is created with the file (in this case E:/project pah/public/uploads/tmp/1515418372-4328-0043-1599/video.mp4) in it. Image temporary files exists, too and the files are in their directories (store_dir). In the database at the first time everything is inserted, but because of this error it rollback.

Aucun commentaire:

Enregistrer un commentaire