William Romero
William Romero

Reputation: 185

How store an image from URL with Active Storage

My question is about: How can i upload an image from URL when i'm using Active Storage. I used the code from other post here in Stackoverflow but passing through the model method, the param which i need to store in my table. The curiously situation is that i'm receiving the next error:

ActiveSupport::MessageVerifier::InvalidSignature in PostsController#update

But when i reload the show view, from this model, the images appears stored and deployed on my posts view.

Here my code in Post model:

class Post < ApplicationRecord
  require 'open-uri'

  has_one_attached :image_one
  has_one_attached :image_two
  has_one_attached :url_image

  before_save :grab_image

  
  def grab_image(url)
    downloaded_image = open(url)
    self.url_image.attach(io: downloaded_image, filename: "map.jpg", content_type:"image/jpg")
  end
  
end

This is my code in the Edit Action of my Controller:

  def update
    @posturl = params[:post][:url_image]
    @post.grab_image(@posturl)
    respond_to do |format|
      if @post.update!(post_params)
        format.html { redirect_to @post, notice: 'Post was successfully updated.' }
        format.json { render :show, status: :ok, location: @post }
      else
        format.html { render :edit }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

Apparently, the record is saved but i receive this problem

I got the following links which talks about the chance to upload images from URLs but, i don´t know what else can i do:

Active Storage Overview - EdgeGuides

@omnilord/rails-5-2-activestorage-mitigating-adoption-pitfalls

Upvotes: 5

Views: 6996

Answers (4)

Kartikey Tanna
Kartikey Tanna

Reputation: 1459

While editing, you need to provide the signed id of the attached blob in case the user did not make any changes to the image.

Something like the below should work. You need to make this change in your form.

<%= form.file_field :image_one, value: image_one.blog.signed_id %>

Upvotes: 0

Pushp Raj Saurabh
Pushp Raj Saurabh

Reputation: 1194

The simplest way to do this without having to enter filename explicitly is:

require 'open-uri'

url = URI.parse("https://your-url.com/abc.mp3")
filename = File.basename(url.path)
file = URI.open
user = User.first
user.avatar.attach(io: file, filename: filename)

This automatically saves the avatar against that particular user object.

In case you are using a remote service like S3 the URL can be retrieved by:

user.avatar.service_url

Upvotes: 2

Valentin Palacios
Valentin Palacios

Reputation: 41

Maybe this work for u:

file = open(url)
user.image.attach(io: file, filename: "temp.#{file.content_type_parse.first.split("/").last}", content_type: file.content_type_parse.first)

Upvotes: 3

Kiryl Plyashkevich
Kiryl Plyashkevich

Reputation: 2267

Here is an example:

file_url = image[:image_url]
download = open(file_url)
IO.copy_stream(download,
user.image.attach(
  io: download,
  filename: image[:name],
  content_type: image[:content_type],
))

Upvotes: 1

Related Questions