Active Storage
sources:
- https://www.engineyard.com/blog/active-storage
- https://edgeguides.rubyonrails.org/active_storage_overview.html
Installation & configuration
Create storage tables:
rails active_storage:install
rails db:migrate
Configuration:
# config/storage.yml
local:
service: Disk
root: <%= Rails.root.join("storage") %>
test:
service: Disk
root: <%= Rails.root.join("tmp/storage") %>
amazon:
service: S3
access_key_id: ""
secret_access_key: ""
region: ""
bucket: ""
Declare configuration per environments:
# config/environments/development.rb
config.active_storage.service = :local
# config/environments/test.rb
config.active_storage.service = :test
# config/environments/production.rb
config.active_storage.service = :amazon
Handling attachments
In ActiveRecords
Update models:
class Catalog < ApplicationRecord
has_one_attached :picture
end
class Article < ApplicationRecord
has_many_attached :pictures
end
Rails forms
In forms files:
# in catalog forms
<%= f.file_field :picture %>
# in article forms
<%= f.file_field :picture, multiple: true %>
In controllers:
# Catalog controller
class CatalogsController
# Filter catalogs parameters
def catalog_params
params.require(:catalog).permit(:other_fields, :picture)
end
end
# Article controller
class ArticlesController
def update_entity
article = Article.find(params[:id])
article.update(article_params)
article.pictures.attach(params[:pictures])
article
end
# Filter articles parameters
def article_params
params.require(:article).permit(:other_fields, pictures: [])
end
end
Rails views
Conditional rendering
To check if picture has an attachment, use picture.attached?
or check picture.attachment.nil?
. image_tag
is an useful helper for rendering an <img />
tag.
Single picture
# in some helper file
def display_picture(picture)
return 'no picture' if picture.attachment.nil?
image_tag picture
end
More about image_tag
Multiple pictures
<% article.pictures.each do |picture| %>
<%= image_tag picture, height: '200', alt: article.name + ' picture', title: article.name %>
<% end %>
Serialization
class CatalogSerializer < ActiveModel::Serializer
# optional attributes
attribute :picture_url, if: -> { object.picture.attached? }
def picture_url
Rails.application.routes.url_helpers.rails_blob_path(object.picture, only_path: true)
end
end
Multiple picture:
- use
has_many_attached
- input form allows multiple upload:
<%= f.file_field :pictures, multiple: true %>
- strong parameters is an array:
permit(pictures: [])
- update must attach new pictures:
article.pictures.attach(params[:pictures])
AWS
https://medium.com/alturasoluciones/setting-up-rails-5-active-storage-with-amazon-s3-3d158cf021ff
region name: https://docs.aws.amazon.com/general/latest/gr/rande.html
do not forget aws-sdk-s3
gem
Sources:
Mentionned: