Rails Active Storage & AWS S3 : How to attach image to model through seeds.rb and then store it in S3 private bucket?

Viewed 1020

For a school project, I'm working on a Rails app which "sells" pics of kittens. I picked 10 pictures of cats online, they are currently on my computer. I'm using Postgresql for the DB. I have a class/model Item which represents the kitten photos.

What I'm looking for is a way to, when generating fake data through seeds.rb loops, attaching a kitten photo to each Item class/model, which will be then stored to an AWS S3 bucket that is already created (it's called catz-temple). I have my two access and secret S3 keys on a .env file, I already have modified my storage.yml file like so :

amazon:
    service: S3
    access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %>
    secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %>
    region: eu-central-1
    bucket: catz-temple

I found out there was a gem called aws-sdk-ruby, but I just can't find out what approach I should have on this topic.

For now, I just put my bucket in public access and take each bucket photos' urls, but there's no API and secure approach into this...

Thank you all

1 Answers

Starting by follow the guides for configuring ActiveStorage and S3. Then setup the attachments on your model.

class Kitteh < ApplicationRecord
  has_one_attached :photo
end

With ActiveStorage you can directly attach files to records by passing an IO object:

photos = Rails.root.join('path/to/the/images', '*.{jpg,gif,png}')
100.times do |n|
  path = photos.sample
  File.open(path) do |file|
    Kitteh.new(name: "Kitteh #{n}") do |k|
      k.photo.attach(
        io: file,
        filename: path.basename 
      )
    end.save!
  end
end

This example creates 100 records with a random image selected from a directory on your hard drive and will upload it to the storage you have configured.

Related