Search code examples
ruby-on-railsrubyimagecloudinaryrails-activestorage

Attach Cloudinary image to Rails model using ActiveStorage


I have a user model

class User < ApplicationRecord
  has_one_attached :photo
end

I'm trying to:

  • upload an image to Cloudinary via URL (this works)
  • attach it to a user instance which uses ActiveStorage (this does not)

Here is what I think should work

user_img_response = Cloudinary::Uploader.upload("https://www.formula1.com/content/dam/fom-website/manual/Misc/2019-Races/Monaco2019/Monaco%20chicane%20HAM%20VER%20sized.jpg.transform/9col/image.jpg")

img_id = user_img_response["url"].match(/image\/upload.*/)[0]
signature = "#{img_id}##{user_img_response["signature"]}"

preloaded_file = Cloudinary::PreloadedFile.new(signature)
user = User.new(title: "Chris")
user.photo = preloaded_file

user.save
=> true

However, the photo is not being attached to the user instance

user.photo.attached? 
=> false

Solution

  • Assuming your app/models/photo.rb looks similar to this:

    class Photo < ActiveRecord::Base
      attr_accessible :title, :bytes, :image, :image_cache
    
      belongs_to :album
    
      mount_uploader :image, ImageUploader
    
      validates_presence_of :title, :image
    end
    

    What happens if you try:

    ...
    user = User.new(title: "Chris")
    user.photo.image = preloaded_file # <---- assign file to image attribute
    user.save
    

    You can also try to emulate this sample app for your case: https://github.com/cloudinary/cloudinary_gem/tree/master/samples/photo_album

    EDIT: you can try something like this:

    require 'uri'
    
    file = URI.open(user_img_response["url"]) # use cloudinary url
    photo.image.attach(io: file, filename: 'image.jpg') 
    

    See: https://blog.eq8.eu/til/upload-remote-file-from-url-with-activestorage-rails.html