如何通过ActiveStorage上传图片
class Medium < ActiveRecord::Base has_one_attached :image end Ruby
Attach remote file
with ‘require open-uri’
require 'open-uri'
file = open('https://meme.eq8.eu/noidea.jpg')
medium = Medium.last
medium.image.attach(io: file, filename: 'some-image.jpg')
# or
medium.image.attach(io: file, filename: 'some-image.jpg', content_type: 'image/jpg')
RubyOr without require
require 'uri'
file = URI.open('https://meme.eq8.eu/noidea.jpg')
medium = Medium.last
medium.image.attach(io: file, filename: 'some-image.jpg')
# or
medium.image.attach(io: file, filename: 'some-image.jpg', content_type: 'image/jpg')
RubyIf you want to get filename from url
require 'uri'
uri = URI.parse('https://meme.eq8.eu/noidea.jpg')
filename = File.basename(uri.path)
RubySo put all that together
require 'uri'
url = 'https://meme.eq8.eu/noidea.jpg'
filename = File.basename(URI.parse(url).path)
file = URI.open('https://meme.eq8.eu/noidea.jpg')
medium = Medium.last
medium.image.attach(io: file, filename: filename, content_type: 'image/jpg')
Rubyto get the mimetype you can use Rack::Mime.mime_type('.jpg') from the ".#{url.split('.').last}
Attach local file
medium = Medium.last
medium.image.attach(io: File.open("/tmp/some-image.jpg"), filename: "some-image.jpg", content_type: "image/jpg")
RubyIf you want to get filename and mime_type from the file:
filename = File.basename("/tmp/some-image.jpg") # => some-image.jpg
extension = File.extname("/tmp/some-image.jpg") # => .jpg
mime_type = Rack::Mime.mime_type(a) #=> "image/jpeg"
Rubyor with Pathname
pathname = Pathname.new('/tmp/some-image.jpg')
pathname.basename.to_s # => some-image.jpg
pathname.extname # => .jpg
Rack::Mime.mime_type(pathname.extname) # => "image/jpeg"
Rubyall together:
medium = Medium.last
pathname = Pathname.new('/tmp/some-image.jpg')
medium.image.attach(io: File.open(pathnname), filename: pathname.basename.to_s, content_type: Rack::Mime.mime_type(pathname.extname))
RubyAttach local file as a uploaded medium
Sometimes you want the file in a console to appear as it was uploaded via a Controller.
For example if you are writing a db:seed where you attach local file you may want to reuse bit of functionality that uses bit of controller logic:
medium.image = params.permit(:image) Ruby
so Here you wont be able to do medium.image.attach(io: File.open('...'), content_type: '...')
Solution:
# app/controller/media_controller.rb
# ...
def create
# ...
Medium.upload_via_controller(params[:image])
# ...
end
end
Ruby# app/models/medium.rb
class Medium < ActiveRecord::Base
has_one_attached :image
def self.upload_via_controller(file_from_controller)
medium = Medium.new
medium.image = file_from_controller
# ...some other logic like set default order
medium.save
end
end
Ruby# lib/tasks/create_dummy_data.rake
module MyRakeHelper
extend ActionDispatch::TestProcess
def self.create_dummy_medium
img = Rails.root.join('db/data/dummy-work.jpg')
img = dummy_file_uplod(img.to_s, 'image/jpg')
## ...or:
# img = dummy_file_uplod(img.to_s, Rack::Mime.mime_type(img.extname))
Medium.upload_via_controller(img) # we want to reuse existing logic in our raketask
end
def self.dummy_file_uplod(file_fixture_path, type)
Rack::Test::UploadedFile.new(file_fixture_path, type)
end
end
task create_dummy_images: :environment do
MyRakeHelper.create_dummy_medium
end
RubyNote: For tests you could use:
# spec/my_spec.rb
# require 'action_dispatch/testing/test_proces' # may be needed
module UploadHelper
extend ActionDispatch::TestProcess::FixtureFile # rails 6
# extend ActionDispatch::TestProcess # order Rails like rails 3.2
def upload(img)
fixture_file_upload(img.to_s, Rack::Mime.mime_type(img.extname))
end
end
it do
img = UploadHelper.upload( Rails.root.join('spec/fixtures/myimg.jpg) )
medium = Medium.create(image: img)
# ...
end
Ruby- https://api.rubyonrails.org/classes/ActionDispatch/TestProcess/FixtureFile.html
- https://github.com/rails/rails/blob/83217025a171593547d1268651b446d3533e2019/actionpack/lib/action_dispatch/testing/test_process.rb#L19
Sources
- https://edgeguides.rubyonrails.org/active_storage_overview.html#attaching-file-io-objects
- https://blog.eq8.eu/til/factory-bot-trait-for-active-storange-has_attached.html
Related articles
- Factory Bot trait for attaching ActiveStorange has_attached
- How to store image width & height in Rails ActiveStorage
- Rails ActiveStorage - crop and resize image variant
- change host in active storage
阅读量: 1002
发布于:
修改于:
发布于:
修改于: