Search code examples
ruby-on-railsamazon-s3seedrails-activestorage

How to seed database from S3 in a RoR app


I loaded images in my bucket in S3 and I want to require these files in my seed.

Here's my actual seed.rb (which use my images stored in local via active storage) :

require 'faker'

Item.destroy_all

20.times do |i|
    item = Item.create!(
                    title: Faker::Games::Pokemon.name,
                    description: Faker::Lorem.paragraph_by_chars(60, false),
                    price: 5.0)
    item.image.attach(io: File.open("app/assets/images/chatons/#{i}.jpg"), filename: "#{i}.jpg")

end

So I have two simple questions :

  • firstly, is it possible ?
  • and if yes, how do I have to proceed ?

Solution

  • Yes, it is possible to seed a db from files in an AWS S3 object store. You will need the AWS_SDK for Ruby

    I've amended your seeds.rb file below:

    require 'faker'
    require 'aws-sdk-s3' 
    
    s3 = Aws::S3::Resource.new(region: 'us-west-2') # Change this to your region
    
    Item.destroy_all
    
    20.times do |i|
        item = Item.create!(
                        title: Faker::Games::Pokemon.name,
                        description: Faker::Lorem.paragraph_by_chars(60, false),
                        price: 5.0)
    
        # Create the object to retrieve
        obj = s3.bucket('my-bucket').object('#{i}.jpg')    # change this to your bucket name
    
        # Get the item's content and save it to local
        obj.get(response_target: 'app/assets/images/chatons/#{i}.jpg')
    
        item.image.attach(io: File.open("app/assets/images/chatons/#{i}.jpg"), filename: "#{i}.jpg")
    
    end
    

    I'm sure this could be optimised. For example, you may not need to save it locally, or perhaps the local version could be deleted after attaching the image.

    The AWS SDK for Ruby documentation explains how to set your aws credentials as environment variables, so you don't need to have your images publicly accessible.