问题
I want to configure an upload path for Carrier wave Direct,which I am using to upload files directly to Amazon s3.In app/uploaders/myuploader.rb ,I have,
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
I want to modify this so that,the path looks like,
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{User.name}".
so it will be some thing like,
"uploads/Users/avatar/michael_jordan/.."
Where User is the model in which the uploader is mounted.
I have gone through the source code of Carrier wave Gem in github(https://github.com/dwilkie/carrierwave_direct) and I couldn't figure out how to pass a value from the active model object to the uploader to create the upload path(key for amazon s3). Is there a way to do this?
Thanks!
Dragon
回答1:
Ok.after one month I was forced to work on the same problem and this time I nailed it.Posting my solution here so that it may help others having the same problem, 1)Override store_dir such that it returns an empty string,
def store_dir
""
end
2)got to your controller and assign your preferred key to the "key" attribute of your uploader object like,
@uploader = @player.avatar
@uploader.key =@player.name +"/\${filename}"
#say if player name in is jordan and the filename is jordan.jpg.
#the uplaod path now will be
#http://bucketname/jordan/jordan.jpg.
here player is the model object,avatar is the property on which the uploader is mounted and the key will be set as playername/filename.
Which was what I was looking for :)
回答2:
If model.name
doesn't work, you can try accessing directly the name field with the #read_attribute method
So your store_dir method would look something like
def store_dir
uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.send(:name)}
end
But I believe model.name
should work
回答3:
The first provided solution did not work for me. After troubleshooting this all day, I checked out the code that dynamically creates the key:
https://github.com/dwilkie/carrierwave_direct/blob/master/lib/carrierwave_direct/uploader.rb
# as defined in carrierwave_direct/uploader.rb
def key
return @key if @key.present?
if present?
self.key = URI.parse(URI.encode(url, " []+()")).path[1 .. -1] # explicitly set key
else
@key = "#{store_dir}/#{guid}/#{FILENAME_WILDCARD}"
end
@key
end
Sheesh. Rather than try to override this method, I just overrode the store_dir and guid methods directly in the uploader:
def store_dir
"#{model.group.id}/photos"
end
def guid
Time.now.utc.strftime("%Y-%m-%d-%H%M%S")
end
Hope this helps someone.
回答4:
https://github.com/gilcierweb/CMS-Rails
# app/uploads/galeria_imagem_uploader.rb
class GaleriaImagemUploader < CarrierWave::Uploader::Base
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}#{model.galeria_id}"
end
end
# app/models/adm/galeria_imagem.rb
class Adm::GaleriasImagem < ActiveRecord::Base
belongs_to :galeria, :polymorphic => true
validates :galeria, presence: true
# GaleriasImagem uploader using carrierwave
mount_uploader :imagem, GaleriaImagemUploader
end
# app/models/adm/galeria.rb
class Adm::Galeria < ActiveRecord::Base
has_many :galerias_imagens, :inverse_of => :galeria, :dependent => :destroy
# enable nested attributes for galerias_imagens through galeria class
accepts_nested_attributes_for :galerias_imagens, allow_destroy: true
end
# app/controllers/adm/galerias_controller.rb
class Adm::GaleriasController < ApplicationController
def create
@adm_galeria = Adm::Galeria.new(adm_galeria_params)
respond_to do |format|
if @adm_galeria.save
# to handle multiple images upload on create
if params[:adm_galeria][:imagem]
params[:adm_galeria][:imagem].each { |image|
@adm_galeria.galerias_imagens.create(imagem: image)}
end
format.html { redirect_to @adm_galeria, notice: 'Galeria was successfully created.' }
format.json { render :show, status: :created, location: @adm_galeria }
else
format.html { render :new }
format.json { render json: @adm_galeria.errors, status: :unprocessable_entity }
end
end
end
end
# app/controllers/adm/galerias_imagens_controller.rb
class Adm::GaleriasImagensController < ApplicationController
def create
@adm_galerias_imagem = Adm::GaleriasImagem.new(adm_galerias_imagem_params)
@adm_galerias_imagem.save
end
end
来源:https://stackoverflow.com/questions/12738700/upload-path-based-on-a-record-value-for-carrier-wave-direct