Carrierwave; Save images to Production Server and move them?
EDIT: My files are only stored as they are in the cache, not in the store_dir file
I spent hours trying to get this to work, Carrierwave works the way it should locally, but in my production they are only saved in the Cache_dir and the form does not redirect me to the path you specified.
Do I need to move the file from its released TMP folder to where it should be? Or shouldn't this work automatically?
Posting a lot of code in case anyone wants to help.
My file will be saved @:
/releases/20150601122454/public/uploads/tmp/pics/1433164111-29887-8666/elg.jpg
And I am trying to move it with:
require 'fileutils'
tmp = params[:instruction][:image].tempfile
newfile = File.join("public/system/pics",params[:instruction][:image].original_filename)
FileUtils.touch('newfile')
FileUtils.copy_file(tmp.path,newfile)
It's just a glitch saying
No such file or directory - public / system / pics / elg.jpg
Its my Image_Uploader:
class ImageUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
include CarrierWave::RMagick
# include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"system/uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
def cache_dir
"uploads/tmp/pics"
end
This is how I update my model:
def update
file = params[:instruction][:image]
puts @instruction.text + " HERE IT IS " +file.path
@instruction.image = file
@instruction.save
Rails.logger.info("@inst.image path: " + @instruction.image.path)
require 'fileutils'
# tmp = params[:instruction][:image].tempfile
# newfile = File.join("public/system/pics",params[:instruction][:image].original_filename)
#FileUtils.touch('newfile')
#FileUtils.copy_file(tmp.path,newfile)
if @instruction.update(instruction_params)
redirect_to instructions_path, notice: 'Instruktionerna sparades.'
else
render action: 'edit' , alert: 'Misslyckades att uppdatera instruktionerna'
end
end
def instruction_params
params.require(:instruction).permit(:text,:role_id)
end
My form:
<%= form_for @instruction, :html => {:multipart => true} do |f| %>
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-8 col-lg-8">
<br>
<div>
<%= f.file_field :image%>
<%= f.hidden_field :image_cache %>
</div>
<br>
<div class="form-group">
<%= f.text_area :text, rows: 15, class: "form-control" %>
</div>
</div>
</div>
<%= f.submit 'Spara', class: "btn btn-primary" %>
<% end %>
Model:
class Instruction < ActiveRecord::Base
belongs_to :role
mount_uploader :image, ImageUploader
end
Please, please, I really need help.
source to share
Possible approach # 1 - add/#{Rails.root}/public
File.join("/#{Rails.root}/public/system/pics",params[:instruction][:image].original_filename)
Possible Approach # 2
Make sure Rails has read / write permission to your filesystem.
A link similar to the code I ran in atm production
This is similar to the code we have in production that works well.
class SomeUploader < CarrierWave::Uploader::Base
...
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
if Rails.env.production?
"uploads/prod/#{model.id}"
else if Rails.env.staging?
"uploads/staging/#{model.id}"
else
"uploads/dev/#{model.id}"
end
end
source to share
Try overwriting store_dir:
The following snippets refer to carrier documentation:
Changing the storage directory
To change the location of the uploaded files, simply override the store_dir method:
# Configure carrierwave root directory
# config/initializers/carrierwave.rb
CarrierWave.configure do |config|
config.root = Rails.root
end
# Overwrite store dir
class MyUploader < CarrierWave::Uploader::Base
def store_dir
'public/my/upload/directory'
end
end
This works for file storage as well as Amazon S3 and Rackspace Cloud files. Define store_dir as null if you want to store files at the root level.
If you store files outside of the project root folder, you can define cache_dir the same way:
class MyUploader < CarrierWave::Uploader::Base
def cache_dir
'/tmp/projectname-cache'
end
end
source to share
I solved it by doing this dirty trick:
require 'fileutils'
tmp = @instruction.image
newfile = File.join("/#{Rails.root}/public/system/pics",params[:instruction][:image].original_filename)
if File.exists?(newfile)
else
FileUtils.makedirs("/#{Rails.root}/public/system/pics")
end
FileUtils.mv(tmp.path,newfile)
@instruction.image = File.open(newfile)
@instruction.save
source to share