1

I'm trying to store images using AmazonS3 for my blog using paperclip. The blog has devise gem implemented for login/signup [User] and I want to add image for every user by storing them on Amazon S3. Previously I was storing them in Database and it was working perfectly.

I've already searched a lot but couldn't find a fix for this.

        //Development.rb
    config.paperclip_defaults = {
      storage: :s3,
        s3_credentials: {
          bucket: ENV.fetch('S3_BUCKET_NAME'),
          access_key_id: ENV.fetch('AWS_ACCESS_KEY_ID'),
          secret_access_key: ENV.fetch('AWS_SECRET_ACCESS_KEY'),
          s3_region: ENV.fetch('AWS_REGION'),
        }
      }

    //AddAttachment Migration
    class AddAttachmentImageToUsers < ActiveRecord::Migration[5.2]
      def self.up
        change_table :users do |t|
          t.attachment :image
        end
      end

      def self.down
        remove_attachment :users, :image
      end
    end

    //User.rb
    class User < ActiveRecord::Base
      # Include default devise modules. Others available are:
      # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
      devise :database_authenticatable, :registerable,
             :recoverable, :rememberable, :validatable

      has_many :comments, dependent: :destroy
      has_many :likes, dependent: :destroy
      has_many :articles

      has_attached_file :image, :styles => { :medium => "300x300>", :thumb => "100x100>"}

      validates_attachment_content_type :image, content_type: /\Aimage\/.*\z/
    end

    //Application.yml
    AWS_ACCESS_KEY_ID: -----
    AWS_SECRET_ACCESS_KEY: ------
    S3_BUCKET_NAME: -------------
    AWS_REGION: ap-south-1

    //Application.html.erb
   <!DOCTYPE html>
<html>
  <head>
    <title> TheBlog</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
  </head>

  <body>

    <nav class="navbar navbar-inverse">
  <div class="container-fluid">
    <div class="navbar-header">
      <a class="navbar-brand" href="#" id="logo">The Blog</a>
    </div>
    <ul class="nav navbar-nav">
      <li class="active">
        <%= link_to 'Home', root_path %></li>
        <li><%= link_to 'About', about_path %></li>
    </ul>

    <ul class="nav navbar-nav navbar-right">
      <% if user_signed_in? %>
        <li>  <%= image_tag current_user.image.url, size:"40x40" %></li>
        <li><%= link_to current_user.email, edit_user_registration_path %></li>
        <li><%= link_to "Logout", destroy_user_session_path, method: :delete %></li>
        <% else %>
      <li><%= link_to "Sign Up", new_user_registration_path %></li>
      <li><%= link_to "Login", new_user_session_path %></li>
      <% end %>
    </ul>
  </div>
</nav>

    <%= yield %>
  </body>
</html>
srijan439
  • 401
  • 5
  • 7

1 Answers1

0

Looks like the same issue as: https://railsblogs.rohityadav.in/2018/01/awss3errorsaccessdenied-access-denied.html

If you get this error when trying to upload to S3, you need to assign this IAM User the “AmazonS3FullAccess” Policy.

Or it might be an issue with heroku config:

AWS::S3::Errors::AccessDenied. Cannot save to S3 with Ruby on Rails

You need to set your AWS credentials as config variables in heroku (basically environment variables). You can check if they are set with heroku config; if they are not set, you can add them with heroku config:set S3_BUCKET_NAME=something AWS_ACCESS_KEY_ID=whatever AWS_SECRET_ACCESS_KEY=something_secret. More info with heroku config --help

Mark
  • 6,112
  • 4
  • 21
  • 46
  • Finally it's working The aws bucket was not public. Secondly the hostname line was missing. config.paperclip_defaults = { storage: :s3, s3_host_name: "s3-#{ENV['AWS_REGION']}.amazonaws.com", s3_credentials: { bucket: ENV.fetch('S3_BUCKET_NAME'), access_key_id: ENV.fetch('AWS_ACCESS_KEY_ID'), secret_access_key: ENV.fetch('AWS_SECRET_ACCESS_KEY'), s3_region: ENV.fetch('AWS_REGION'), } } – srijan439 Jan 16 '19 at 12:46
  • Happy to help :) – Mark Jan 16 '19 at 14:10