Upload path based on a record value for Carrier wave Direct

江枫思渺然 提交于 2021-02-18 18:11:35

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!