Skip to content

Commit

Permalink
Migrate from paperclip to activestorage
Browse files Browse the repository at this point in the history
  • Loading branch information
RyanTG committed Jan 31, 2025
1 parent 4891ddd commit 0113af8
Show file tree
Hide file tree
Showing 20 changed files with 149 additions and 32 deletions.
2 changes: 1 addition & 1 deletion .env.local.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ MAPBOX_KEY=placeholder
WEB_CONCURRENCY=0 # run in solo mode instead of clustering for development
AWS_SECRET_ACCESS_KEY=placeholder
AWS_ACCESS_KEY_ID=placeholder
AWS_PICTURE_PATH=https://s3.amazonaws.com/<replace with bucketname>/location_picture_xref/photo/:id/medium/:filename
AWS_REGION=
AWS_BUCKET_NAME=
GOOGLE_MAPS_API_KEY=
HERE_MAPS_API_KEY=
MAPBOX_DEV_API_KEY=
Expand Down
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ gem "exception_notification"
gem "geocoder"
gem "haml-rails"
gem "has_scope"
gem "image_processing"
gem "inherited_resources"
gem "kaminari"
gem "kt-paperclip"
Expand Down
8 changes: 8 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,9 @@ GEM
htmlentities (4.3.4)
i18n (1.14.6)
concurrent-ruby (~> 1.0)
image_processing (1.13.0)
mini_magick (>= 4.9.5, < 5)
ruby-vips (>= 2.0.17, < 3)
inherited_resources (2.0.1)
actionpack (>= 6.0)
has_scope (>= 0.6)
Expand Down Expand Up @@ -269,6 +272,7 @@ GEM
mime-types-data (~> 3.2015)
mime-types-data (3.2024.0305)
mini_histogram (0.3.1)
mini_magick (4.13.2)
mini_mime (1.1.5)
mini_portile2 (2.8.8)
minitest (5.25.4)
Expand Down Expand Up @@ -439,6 +443,9 @@ GEM
rubocop (~> 1.61)
ruby-progressbar (1.13.0)
ruby-statistics (3.0.1)
ruby-vips (2.2.2)
ffi (~> 1.12)
logger
rubyzip (2.3.2)
sanitize (6.1.3)
crass (~> 1.0.2)
Expand Down Expand Up @@ -553,6 +560,7 @@ DEPENDENCIES
geocoder
haml-rails
has_scope
image_processing
inherited_resources
kaminari
kt-paperclip
Expand Down
31 changes: 31 additions & 0 deletions app/assets/stylesheets/actiontext.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Provides a drop-in pointer for the default Trix stylesheet that will format the toolbar and
* the trix-editor content (whether displayed or under editing). Feel free to incorporate this
* inclusion directly in any other asset bundle and remove this file.
*
*= require trix
*/

/*
* We need to override trix.css’s image gallery styles to accommodate the
* <action-text-attachment> element we wrap around attachments. Otherwise,
* images in galleries will be squished by the max-width: 33%; rule.
*/
.trix-content .attachment-gallery > action-text-attachment,
.trix-content .attachment-gallery > .attachment {
flex: 1 0 33%;
padding: 0 0.5em;
max-width: 33%;
}

.trix-content .attachment-gallery.attachment-gallery--2 > action-text-attachment,
.trix-content .attachment-gallery.attachment-gallery--2 > .attachment, .trix-content .attachment-gallery.attachment-gallery--4 > action-text-attachment,
.trix-content .attachment-gallery.attachment-gallery--4 > .attachment {
flex-basis: 50%;
max-width: 50%;
}

.trix-content action-text-attachment .attachment {
padding: 0 !important;
max-width: 100% !important;
}
1 change: 0 additions & 1 deletion app/controllers/pages_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
class PagesController < ApplicationController
respond_to :xml, :json, :html, :js, :rss


def contact_sent
user = current_user.nil? ? nil : current_user
return if params["contact_msg"].blank? || (!user && params["contact_email"].blank?) || params["contact_msg"].match?(/vape/) || params["contact_msg"].match?(/seo/) || params["contact_msg"].match?(/Ezoic/)
Expand Down
3 changes: 3 additions & 0 deletions app/mailboxes/application_mailbox.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class ApplicationMailbox < ActionMailbox::Base
# routing /something/i => :somewhere
end
18 changes: 2 additions & 16 deletions app/models/location_picture_xref.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,15 @@ class LocationPictureXref < ApplicationRecord
belongs_to :location, optional: true
belongs_to :user, optional: true

has_attached_file :photo,
storage: :s3,
bucket: "pbm-images",
path: "location_picture_xref/photo/:id/:style/:filename",
url: ENV.fetch("AWS_PICTURE_PATH", "https://s3.amazonaws.com/pbm-images/location_picture_xref/photo/:id/medium/:filename"),
styles: {
thumb: "36x25>",
medium: "300x300>",
large: "800x800>"
},
s3_credentials: {
access_key_id: ENV["AWS_ACCESS_KEY_ID"],
secret_access_key: ENV["AWS_SECRET_ACCESS_KEY"]
},
s3_region: ENV["AWS_REGION"]
has_one_attached :photo

do_not_validate_attachment_file_type :photo

def rails_admin_default_object_label_method; end

def create_user_submission
user_info = user ? user.username : "UNKNOWN USER"
submission = "#{user_info} added a picture of #{location.name} in #{location.city}#{photo.nil? ? '' : ': https:' + photo.url(:large)}"
submission = "#{user_info} added a picture of #{location.name} in #{location.city}"

UserSubmission.create(user_name: user.username, location_name: location.name, city_name: location.city, lat: location.lat, lon: location.lon, region_id: location.region_id, location: location, submission_type: UserSubmission::NEW_PICTURE_TYPE, submission: submission, user: user)
Rails.logger.info "USER SUBMISSION USER ID #{user&.id} #{submission}"
Expand Down
14 changes: 14 additions & 0 deletions app/views/active_storage/blobs/_blob.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<figure class="attachment attachment--<%= blob.representable? ? "preview" : "file" %> attachment--<%= blob.filename.extension %>">
<% if blob.representable? %>
<%= image_tag blob.representation(resize_to_limit: local_assigns[:in_gallery] ? [ 800, 600 ] : [ 1024, 768 ]) %>
<% end %>
<figcaption class="attachment__caption">
<% if caption = blob.try(:caption) %>
<%= caption %>
<% else %>
<span class="attachment__name"><%= blob.filename %></span>
<span class="attachment__size"><%= number_to_human_size blob.byte_size %></span>
<% end %>
</figcaption>
</figure>
3 changes: 3 additions & 0 deletions app/views/layouts/action_text/contents/_content.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div class="trix-content">
<%= yield -%>
</div>
2 changes: 1 addition & 1 deletion app/views/location_picture_xrefs/_form.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
%span.red.font14.p_10.block Choose a picture that gives a feel for the place. No need to include a picture of every single machine.
= form_for LocationPictureXref.new, :id => "new_location_picture_xref_#{l.id}", :html => {:id => "new_location_picture_xref_#{l.id}", :multipart => true}, :remote => true do |f|
= f.hidden_field :location_id, { :value => l.id }
= f.file_field :photo, :id => 'file_chooser_button'
= f.file_field :photo, :id => 'file_chooser_button', :direct_upload => true
%br/
= f.submit "Upload", :class => 'submit_picture'

Expand Down
4 changes: 2 additions & 2 deletions app/views/location_picture_xrefs/_show_thumbs.html.haml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
- location_picture_xrefs.each do |lpx|
- if lpx.photo?
= link_to image_tag(lpx.photo.url(:medium)), lpx.photo.url(:large), :class => "location_thumb location_picture_xref_#{lpx.id}", :"data-lightbox" => "location_thumb"
- if lpx.photo.attached?
= link_to image_tag(lpx.photo.variant(resize_to_limit: [100,100])), lpx.photo.variant(resize_to_limit: [800,800]), :class => "location_thumb location_picture_xref_#{lpx.id}", :"data-lightbox" => "location_thumb"
= render :partial => 'location_picture_xrefs/remove_picture', :locals => {:lpx => lpx}
3 changes: 2 additions & 1 deletion config/environments/development.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
end

# Store uploaded files on the local file system (see config/storage.yml for options).
config.active_storage.service = :local
config.active_storage.service = :amazon
config.active_storage.variant_processor = :vips

# Don't care if the mailer can't send.
config.action_mailer.raise_delivery_errors = false
Expand Down
3 changes: 2 additions & 1 deletion config/environments/production.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
# config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX

# Store uploaded files on the local file system (see config/storage.yml for options).
config.active_storage.service = :local
config.active_storage.service = :amazon
config.active_storage.variant_processor = :vips

# Mount Action Cable outside main process or domain.
# config.action_cable.mount_path = nil
Expand Down
3 changes: 2 additions & 1 deletion config/environments/staging.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
# config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX

# Store uploaded files on the local file system (see config/storage.yml for options).
config.active_storage.service = :local
config.active_storage.service = :amazon
config.active_storage.variant_processor = :vips

# Mount Action Cable outside main process or domain.
# config.action_cable.mount_path = nil
Expand Down
14 changes: 7 additions & 7 deletions config/storage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ local:
service: Disk
root: <%= Rails.root.join("storage") %>

# Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
# 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: your_own_bucket
#Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
amazon:
service: S3
access_key_id: <%= ENV["AWS_ACCESS_KEY_ID"] %>
secret_access_key: <%= ENV["AWS_SECRET_ACCESS_KEY"] %>
region: us-west-1
bucket: <%= ENV["AWS_BUCKET_NAME"] %>

# Remember not to checkin your GCS keyfile to a repository
# google:
Expand Down
26 changes: 26 additions & 0 deletions db/migrate/20250129200229_create_action_text_tables.action_text.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# This migration comes from action_text (originally 20180528164100)
class CreateActionTextTables < ActiveRecord::Migration[6.0]
def change
# Use Active Record's configured type for primary and foreign keys
primary_key_type, foreign_key_type = primary_and_foreign_key_types

create_table :action_text_rich_texts, id: primary_key_type do |t|
t.string :name, null: false
t.text :body, size: :long
t.references :record, null: false, polymorphic: true, index: false, type: foreign_key_type

t.timestamps

t.index [ :record_type, :record_id, :name ], name: "index_action_text_rich_texts_uniqueness", unique: true
end
end

private
def primary_and_foreign_key_types
config = Rails.configuration.generators
setting = config.options[config.orm][:primary_key_type]
primary_key_type = setting || :primary_key
foreign_key_type = setting || :bigint
[ primary_key_type, foreign_key_type ]
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# This migration comes from action_mailbox (originally 20180917164000)
class CreateActionMailboxTables < ActiveRecord::Migration[6.0]
def change
create_table :action_mailbox_inbound_emails, id: primary_key_type do |t|
t.integer :status, default: 0, null: false
t.string :message_id, null: false
t.string :message_checksum, null: false

t.timestamps

t.index [ :message_id, :message_checksum ], name: "index_action_mailbox_inbound_emails_uniqueness", unique: true
end
end

private
def primary_key_type
config = Rails.configuration.generators
config.options[config.orm][:primary_key_type] || :primary_key
end
end
19 changes: 19 additions & 0 deletions lib/tasks/migrate_paperclip.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace :location_picture_xrefs do
task migrate_to_active_storage: :environment do
LocationPictureXref.where.not(photo_file_name: nil).find_each do |lpx|
# This step helps us catch any attachments we might have uploaded that
# don't have an explicit file extension in the filename
image_original = lpx.photo_file_name
# ext = File.extname(image)
# image_original = CGI.unescape(image.gsub(ext, "_original#{ext}"))

# this url pattern can be changed to reflect whatever service you use
lpx_url = "https://s3.amazonaws.com/pbm-images/location_picture_xref/photo/#{lpx.id}/original/#{image_original}"
lpx.photo.attach(io: OpenURI.open_uri(lpx_url),
filename: lpx.photo_file_name,
content_type: lpx.photo_content_type)
rescue OpenURI::HTTPError, URI::InvalidURIError => e
puts "bad image path #{lpx_url}"
end
end
end
2 changes: 1 addition & 1 deletion spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# rubocop:disable Style/MixinUsage
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV['RAILS_ENV'] = 'test'
ENV['AWS_REGION'] = 'us-east-1'
ENV['AWS_REGION'] = 'us-west-1'
require File.expand_path('../../config/environment', __FILE__)
require 'factory_bot_rails'
require 'rspec/rails'
Expand Down
4 changes: 4 additions & 0 deletions test/fixtures/action_text/rich_texts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# one:
# record: name_of_fixture (ClassOfFixture)
# name: content
# body: <p>In a <i>million</i> stars!</p>

0 comments on commit 0113af8

Please sign in to comment.