Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Carrierwave not uploading the file. #154

Open
nsantiago2719 opened this issue Feb 26, 2016 · 14 comments
Open

Carrierwave not uploading the file. #154

nsantiago2719 opened this issue Feb 26, 2016 · 14 comments

Comments

@nsantiago2719
Copy link

I have been using carrierwave-mongoid for my projects. But this is the first time that I encounter this problem. I'm trying to upload a Avatar for the user. I have mounted the uploader, configure the options, and followed the steps every time I use carrierwave. But after uploading the avatar field turns out to old every image upload. Here's a code in my controller

def create
  @user = User.new(data)
  if @user.save
    if params[:user][:avatar].present?
      @user.avatar = params[:user][:avatar]
      @user.save
    end
  end
end

I checked the value of params[:user][:avatar] and it returns me the file. But when I checked @user.avatar's value it returns me this path /uploads/user/avatar/56d00fddc001ff0bd5616990/_old_ . Oh and by the way I checked the path but there is nothing.

@Divya-Pandit
Copy link

we are facing same issue.Please,let us know if anyone has found solution for this.

@streetlogics
Copy link

streetlogics commented Apr 23, 2020

For any other poor fool who comes across this at a later date, here you are: use .update(avatar: File.open(params[:user][:avatar])) instead! I don't know why, maybe the maintainers can figure it out, but the avatar= method is not behaving the same as the .update method

@leoarnold
Copy link
Contributor

@nsantiago2719 @Divya-Pandit @streetlogics I tried to tackle this issue but was not able to reproduce it. What am I missing? Here is what I tried:

    describe 'Issue 158' do
      let(:model_class) { reset_mongo_class }

      before do
        model_class.create!
      end

      shared_examples 'persist avatar' do
        if Gem::Version.new(Mongoid::VERSION) >= Gem::Version.new(4)
          it 'save', aggregate_failures: true do
            record = model_class.first
            expect(record.image).to be_blank

            record.image = file
            record.save!

            expect(record.image.path).to eq(public_path('uploads/test.jpeg'))
            expect(model_class.first.image.path).to eq(public_path('uploads/test.jpeg'))
          end

          it 'update', aggregate_failures: true do
            record = model_class.first
            expect(record.image).to be_blank

            expect(record.update(image: file)).to be_truthy

            expect(record.image.path).to eq(public_path('uploads/test.jpeg'))
            expect(model_class.first.image.path).to eq(public_path('uploads/test.jpeg'))
          end
        end
      end

      context 'with stub_file' do
        let(:file) { stub_file('test.jpeg') }

        include_examples 'persist avatar'
      end

      context 'with file upload' do
        let(:file) do
          {
            "filename" => "test.jpeg",
            "type" => "image/jpeg",
            "name" => "avatar",
            "tempfile" => stub_tempfile('test.jpeg'),
            "head" => "Content-Disposition: form-data; name=\"avatar\"; filename=\"test.jpeg\"\r\nContent-Type: image/jpeg\r\n"
          }.with_indifferent_access
        end

        include_examples 'persist avatar'
      end
    end

@nsantiago2719
Copy link
Author

@leoarnold , I'm not sure because this was a project of mine 4 years ago and as far as I remember I didn't proceed to use this since I wasn't able to fix that problem in time.

@streetlogics
Copy link

streetlogics commented Dec 10, 2020

@leoarnold

I tried to tackle this issue but was not able to reproduce it. What am I missing? Here is what I tried:

In my code, I was calling account.avatar = File.open("path/to/file"), I would assume that's how stub_file is behaving but not quite sure. One thought may be to try a .reload on the object or re-query for it to ensure it's not just set there manually on the object but didn't actually get updated.

@leoarnold
Copy link
Contributor

@streetlogics The way you describe works. That's what I use day to day with no observable problem (at least in our setup).

Should anyone experience the same issue: Please be specific in what kind of object you are actually assigning.

My hunch is that - in the initial example - params[:user][:avatar] was not a proper file upload, but rather the file in plain text (not binary), i.e. a String and not a File. Or maybe it was a file path on disc or some URI.

@streetlogics
Copy link

The way you describe works.

  • In your test.

I can assure you it didn't work in my case where I was using File.open, despite your test showing otherwise or what the OP had. Either it's something to do with the way stub_file is working (maybe it's returning an empty file instead of actual contents and that throws it off? ¯_(ツ)_/¯ ), or the object needs to actually be reloaded in your test to see whether the value was actually saved correctly despite it appearing to be the case simply because save! didn't throw an error and the values appear to be set correctly on the object (hence the suggestion of trying to reload the instance to see if it was actually persisted).

@streetlogics
Copy link

Also - what does your uploader look like?

@streetlogics
Copy link

This was what I was using:

class AvatarUploader < CarrierWave::Uploader::Base

  storage :fog

  include CarrierWave::MiniMagick

  # 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
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  def extension_whitelist
    %w(jpg jpeg png)
  end

  process :resize_to_fill => [300, 300]
  
end

@streetlogics
Copy link

Wondering if maybe it could be something to do with the extra step of uploading to s3 via fog?

@leoarnold
Copy link
Contributor

@streetlogics Our uploader looks quite the same. Also uses S3. Maybe your access to S3 lacks certain permissions, leading to a silent fail. I gave mine full permissions on its S3 bucket.

@streetlogics
Copy link

Yah my s3 credentials are setup and working fine. I'm not having the issue anymore as I've implemented my "workaround" using .update instead of avatar = - can't explain why the setter didn't work vs. update, but figured it would help if I posted that and give some guidance on where to look. Take it for what it's worth ¯(ºдಠ)/¯ There's something about your test that's not quite reproducing the issue somehow, but I'm not sure how / what / why. Sorry I don't have more detail to help repro, I know how frustrating these issue can be to try and hunt down. Hopefully if someone else has this issue they have a simpler use case that they can try to post more details on that helps repro.

For reference, here's all the mongo related gems I'm using in case one of them is potentially interacting weirdly:

gem 'mongo', '2.13.0'
gem 'mongoid', github: 'marmont/mongoid', ref: '58d008a06f195c34954275d2c140474336c4a9c5'
gem 'mongoid-slug'
gem 'mongoid_token', github: 'marmont/mongoid_token', ref: 'da951156cf39126dd952bf442ee00fa6037bf18d'
gem "mongo_session_store", '>= 3.2.1'
gem 'mongoid_rails_migrations'
gem 'kaminari-mongoid'
gem 'mongoid-ancestry'
gem 'carrierwave'
gem 'carrierwave-mongoid'
gem 'fog-aws'

@streetlogics
Copy link

Here's my config/initializers/carrierwave.rb in case it helps too, maybe it's something with using cache_storage = :file ¯\_(ツ)_/¯ :

CarrierWave.configure do |config|
  endpoint = "https://xyz.cloudfront.net"
  config.fog_credentials = {
    :provider               => 'AWS',
    :aws_access_key_id      => ENV['AWS_ACCESS_KEY_ID'],
    :aws_secret_access_key  => ENV['AWS_SECRET_ACCESS_KEY'],
    :region                 => 'us-east-1',
    :host                   => "s3.amazonaws.com",
    :endpoint               => "https://s3.amazonaws.com"
  }
  config.cache_storage = :file
  config.fog_directory  = ENV['S3_BUCKET_NAME']
  config.asset_host = endpoint
end

module CarrierWave
  module MiniMagick
    def quality(percentage)
      manipulate! do |img|
        img.quality(percentage.to_s)
        img = yield(img) if block_given?
        img
      end
    end
  end
end

@leoarnold
Copy link
Contributor

@streetlogics When you write update(avatar: File.open(params[:user][:avatar])), what is params[:user][:avatar]?

Can you please paste a sample of

puts params[:user][:avatar].inspect

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants