Loading...
Loading...
Master Rails Active Storage for file attachments, cloud storage integration, image transformations, and direct uploads. Use when implementing file uploads, managing attachments to records, configuring S3/GCS storage, generating image variants, and handling file analysis. Covers local disk, cloud services, direct uploads, and advanced patterns.
npx skill4agent add shivamsinghchahar/rails-skills rails-active-storage# Generate migrations and set up storage tables
rails active_storage:install
rails db:migrateconfig/storage.ymllocal:
service: Disk
root: <%= Rails.root.join("storage") %>
amazon:
service: S3
access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
region: us-east-1
bucket: my-app-<%= Rails.env %>
google:
service: GCS
credentials: <%= Rails.root.join("path/to/keyfile.json") %>
project: my-project
bucket: my-app-<%= Rails.env %>config/environments/development.rbconfig.active_storage.service = :localclass User < ApplicationRecord
has_one_attached :avatar
end<%= form.file_field :avatar, direct_upload: true %>class UsersController < ApplicationController
def create
@user = User.create!(user_params)
redirect_to @user
end
private
def user_params
params.expect(user: [:name, :email, :avatar])
end
enduser.avatar.attach(params[:avatar])
user.avatar.attached? # => trueclass Message < ApplicationRecord
has_many_attached :images
end@message.images.attach(params[:images])
@message.images.attached? # => trueurl_for(user.avatar)
# => https://www.example.com/rails/active_storage/blobs/redirect/:signed_id/avatar.png
rails_blob_path(user.avatar, disposition: "attachment")
# => Download link<%= image_tag user.avatar %>
<%= link_to "Download", rails_blob_path(user.avatar, disposition: "attachment") %>class User < ApplicationRecord
has_one_attached :avatar do |attachable|
attachable.variant :thumb, resize_to_limit: [100, 100]
end
end<%= image_tag user.avatar.variant(:thumb) %>user.avatar.purge # Synchronous
user.avatar.purge_later # Async via Active Jobhas_one_attachedhas_many_attachedfilenamecontent_typebyte_sizechecksummetadatahas_one_attachedhas_many_attachedclass User < ApplicationRecord
has_one_attached :avatar do |attachable|
attachable.variant :medium, resize_to_limit: [400, 400]
attachable.variant :thumb, resize_to_limit: [150, 150]
end
validate :avatar_content_type
private
def avatar_content_type
return unless avatar.attached?
unless avatar.content_type.in?(%w[image/jpeg image/png image/gif])
errors.add(:avatar, "must be a valid image")
end
end
endclass Document < ApplicationRecord
has_one_attached :file
after_create_commit :analyze_document
private
def analyze_document
return unless file.attached?
puts "File: #{file.filename}"
puts "Size: #{file.byte_size} bytes"
puts "Type: #{file.content_type}"
puts "Analyzed: #{file.analyzed?}"
# Use metadata from file.metadata for further processing
end
endclass Post < ApplicationRecord
has_many_attached :images do |attachable|
attachable.variant :display, resize_to_limit: [800, 600]
attachable.variant :thumb, resize_to_limit: [200, 200]
end
end
# In view:
<%= @post.images.each do |image| %>
<%= image_tag image.variant(:display) %>
<% end %># Find users with avatars
User.joins(:avatar_attachment).distinct
# Find messages with only video attachments
Message.joins(:images_blobs).where(active_storage_blobs: { content_type: "video/mp4" })
# Eager load to prevent N+1
Post.includes(:images_attachments, :images_blobs)rails credentials:editconfig/storage/test.ymlincludes(:*_attachments, :*_blobs)