Search code examples
ruby-on-railsherokuamazon-s3carrierwaveimage-uploading

Rails S3 carrierwave upload not working


I've been struggling with this for a while and even though I've googled a bunch, I still can't find the answer to my question. I have a Rails site up on heroku. I am allowing users to create posts and I'd like them to be able to add multiple pics. I am using Rails 4.2.1 with carrierwave and without S3-direct uploads, everthing is working fine.

However, I want to implement direct uploading to Amazon S3. I've tried to implement Heroku's own guide: https://devcenter.heroku.com/articles/direct-to-s3-image-uploads-in-rails

This works -nearly. The form looks great, it works like a charm, and the file (I'm still stuck at just the one atm) gets uploaded to Amazon, with a link and everything. However, it doesn't show up in my app.

To give you an idea what happens, here's my console output:

Started PATCH "/posts/47" for 127.0.0.1 at 2016-04-02 21:46:47     +0200
Processing by PostsController#update as HTML
Parameters: {"utf8"=>"✓",   "authenticity_token"=>"***auth token***", "posts"=>{"image"=>"//myapp.s3.amazonaws.com/uploads/d886f0c3-f51c-48a6-8e00-30a0a278e298/image-that-i-have-uploaded.jpg", "remote_image_url"=>"", "image_cache"=>"", "remove_image"=>"0", "title"=>"test", "description_short"=>"testdescshort2", "description_long"=>"testdesclong2"}, "button"=>"", "id"=>"47"}

Post Load (1.1ms)  SELECT  "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT 1  [["id", 47]]

User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ?  ORDER BY "users"."id" ASC LIMIT 1  [["id", 1]]

Post Load (0.1ms)  SELECT  "posts".* FROM "posts" WHERE "posts"."user_id" = ? AND "posts"."id" = ? LIMIT 1  [["user_id", 1], ["id", 47]]

  (0.2ms)  begin transaction

Post Load (0.2ms)  SELECT  "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT 1  [["id", 47]]

SQL (1.8ms)  UPDATE "posts" SET "image" = ?, "updated_at" = ? WHERE "posts"."id" = ?  [["image", "73811_108472322553034_2478153_n.jpeg"], ["updated_at", "2016-04-02 19:46:48.005926"], ["id", 47]]
 (0.9ms)  commit transaction

Redirected to http://localhost:3000/posts/47
Completed 302 Found in 43ms (ActiveRecord: 4.5ms)

(I've taken the real authenticity token out of this, because I'm not sure if I can share that for privacy reasons.)

As you can see, a link is created for my uploaded image. However, it doesn't load the post with the new image. Instead, it loads the already existing pic.

The same happens when I'm creating a new post - then, it just saves the image as nil.

Does anyone no what I can do? I'm sure I'm just doing something simple wrong, but I can't find it.

Your help is enormously appreciated!!!!


Solution

  • You canto grant access to the S3 Bucket as mentioned above but is not a production-ready solution.

    Instead of sharing a direct S3 Bucket Public URL, use a signature or token base URL. Signature URL expired after a certain time and ensures you about the safe use of S3 Object.

    The sample generated URL will be look like this: https://s3.amazonaws.com/your_bucket/your_folder/1234/124.pdf?AWSAccessKeyId=ACCESSKEY&Signature=4yM%2FF%2F5TV6t4b1IIvjseenRrb%2FY%3D&Expires=1379152321

    Here is a sample snippet for the same:

    CarrierWave.configure do |config|
      config.fog_directory   = s3_bucket
      config.storage         = :fog
      config.fog_credentials = {
        provider:              'AWS',
        aws_access_key_id:     s3_access_key,
        aws_secret_access_key: 3_secret_key,
        region:                s3_region,
        endpoint:              :s3_server_endpoint
      }
      config.fog_public      = false
      config.fog_attributes = {
        'Cache-Control' => 'max-age=0'
      }
    end