5
votes

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

4

4 Answers

3
votes

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)
2
votes

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
1
votes

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],
))
0
votes

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 %>