Skip to content

Commit 6a956aa

Browse files
authored
[refactor] Migrate from Paperclip to ActiveStorage (#152)
* [refactor] Use ActiveStorage instead of Paperclip * Reformat * Add link to original source
1 parent be0d9a3 commit 6a956aa

22 files changed

+155
-94
lines changed

Gemfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ gem 'doorkeeper', '~> 5.0'
4646
gem 'devise-doorkeeper'
4747

4848
# User uploads
49-
gem 'paperclip', '~> 6.0'
50-
gem 'aws-sdk-s3'
49+
gem "aws-sdk-s3", require: false
50+
gem "file_validators"
5151

5252
# Templating utilities
5353
gem 'haml-rails', '~> 1.0'

Gemfile.lock

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ GEM
103103
chromedriver-helper (2.1.1)
104104
archive-zip (~> 0.10)
105105
nokogiri (~> 1.8)
106-
climate_control (0.2.0)
107106
codeclimate-test-reporter (0.6.0)
108107
simplecov (>= 0.7.1, < 1.0.0)
109108
coderay (1.1.2)
@@ -152,6 +151,9 @@ GEM
152151
faraday (0.15.4)
153152
multipart-post (>= 1.2, < 3)
154153
ffi (1.11.1)
154+
file_validators (2.3.0)
155+
activemodel (>= 3.2)
156+
mime-types (>= 1.0)
155157
font-awesome-rails (4.7.0.5)
156158
railties (>= 3.2, < 6.1)
157159
formatador (0.2.5)
@@ -265,12 +267,6 @@ GEM
265267
oauth2 (~> 1.0)
266268
omniauth (~> 1.2)
267269
orm_adapter (0.5.0)
268-
paperclip (6.1.0)
269-
activemodel (>= 4.2.0)
270-
activesupport (>= 4.2.0)
271-
mime-types
272-
mimemagic (~> 0.3.0)
273-
terrapin (~> 0.6.0)
274270
popper_js (1.14.5)
275271
power_assert (1.1.4)
276272
pry (0.12.2)
@@ -413,8 +409,6 @@ GEM
413409
strip_attributes (1.9.0)
414410
activemodel (>= 3.0, < 7.0)
415411
temple (0.8.1)
416-
terrapin (0.6.0)
417-
climate_control (>= 0.0.3, < 1.0)
418412
test-unit (3.3.3)
419413
power_assert
420414
thor (0.20.3)
@@ -470,6 +464,7 @@ DEPENDENCIES
470464
doorkeeper (~> 5.0)
471465
dotenv-rails
472466
factory_bot_rails
467+
file_validators
473468
font-awesome-rails (~> 4.0)
474469
groupdate
475470
guard
@@ -484,7 +479,6 @@ DEPENDENCIES
484479
mustache (~> 1.0)
485480
mysql2 (>= 0.4.4, < 0.6.0)
486481
omniauth-mlh (~> 0.1)
487-
paperclip (~> 6.0)
488482
puma (~> 3.11)
489483
rails (~> 5.2.2)
490484
rails-controller-testing

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ HackathonManager makes use of a few different third-party services & Ruby gems:
3030
- [Devise](https://github.com/plataformatec/devise) + [MyMLH](https://my.mlh.io/) (authentication & attendee identity)
3131
- [Sidekiq](https://github.com/mperham/sidekiq) (background jobs)
3232
- [Sparkpost](https://www.sparkpost.com/) (email)
33-
- [Paperclip](https://github.com/thoughtbot/paperclip) + [Amazon S3](https://aws.amazon.com/s3/) (resume storage)
33+
- [Amazon S3](https://aws.amazon.com/s3/) (resume storage)
3434
- [Chartkick](http://chartkick.com/) (management UI charts)
3535
- [Blazer](https://github.com/ankane/blazer) (custom SQL queries, analytics, and charts)
3636
- [Doorkeeper](https://github.com/doorkeeper-gem/doorkeeper) (authentication via OAuth for API usage)

app/controllers/manage/stats_controller.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ def dietary_special_needs
3131
def sponsor_info
3232
data = Rails.cache.fetch(cache_key_for_questionnaires("sponsor_info")) do
3333
select_attributes = [
34+
:id,
3435
:first_name,
3536
:last_name,
3637
:vcs_url,
3738
:portfolio_url,
3839
:user_id,
39-
:school_id,
40-
:resume_file_name
40+
:school_id
4141
]
4242
json_attributes = [
4343
:first_name,
@@ -47,9 +47,9 @@ def sponsor_info
4747
:vcs_url,
4848
:portfolio_url
4949
]
50-
data = Questionnaire.where("can_share_info = '1' AND checked_in_at != 0").select(select_attributes)
50+
data = Questionnaire.where("can_share_info = '1' AND checked_in_at != 0").joins(:resume_attachment).select(select_attributes)
5151
json = to_json_array(data, json_attributes)
52-
json.map.with_index { |item, index| item.insert(5, data[index].resume? ? data[index].resume.url : '') }
52+
json.map.with_index { |item, index| item.insert(6, data[index].resume.attached? ? url_for(data[index].resume) : '') }
5353
end
5454
render json: { data: data }
5555
end

app/inputs/deletable_attachment_input.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ def input(wrapper_options)
33
merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
44
out = ''
55
out << @builder.file_field(attribute_name, merged_input_options)
6-
if object.send("#{attribute_name}?")
6+
if object.send("#{attribute_name}").attached?
77
out << @builder.input("delete_#{attribute_name}", as: :boolean, label: "Remove?", wrapper_html: { class: 'deletable_attachment_input' })
88
end
99
out.html_safe

app/models/deletable_attachment.rb

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@
22
module DeletableAttachment
33
extend ActiveSupport::Concern
44

5-
included do
6-
attachment_definitions.keys.each do |name|
5+
class_methods do
6+
def deletable_attachment(name, dependent: :purge_later)
77
attr_accessor :"delete_#{name}"
88

9-
before_validation { send(name).destroy if send("delete_#{name}") == '1' }
9+
before_validation { send(name)&.purge if send("delete_#{name}") == '1' }
1010

1111
define_method :"delete_#{name}=" do |value|
1212
instance_variable_set :"@delete_#{name}", value
13-
send("#{name}_file_name_will_change!")
1413
end
1514
end
1615
end

app/models/questionnaire.rb

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
class Questionnaire < ApplicationRecord
22
include ActiveModel::Dirty
3+
include DeletableAttachment
34

45
before_validation :consolidate_school_names
56
before_validation :clean_for_non_rsvp
@@ -28,11 +29,11 @@ class Questionnaire < ApplicationRecord
2829
# validates_presence_of :why_attend
2930
# end
3031

31-
has_attached_file :resume
32-
validates_attachment_content_type :resume, content_type: %w[application/pdf], message: "Invalid file type"
33-
validates_attachment_size :resume, in: 0..2.megabytes, message: "File size is too big"
34-
35-
include DeletableAttachment
32+
has_one_attached :resume
33+
deletable_attachment :resume
34+
validates :resume, file_size: { less_than_or_equal_to: 2.megabytes },
35+
file_content_type: { allow: ['application/pdf'] },
36+
if: -> { resume.attached? }
3637

3738
validates :portfolio_url, url: { allow_blank: true }
3839
validates :vcs_url, url: { allow_blank: true }

app/views/application/_questionnaire_summary.html.haml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
= @questionnaire.vcs_url? ? link_to(@questionnaire.vcs_url, @questionnaire.vcs_url, target: '_blank') : 'Not provided'
1414
%p
1515
%b Resume:
16-
= @questionnaire.resume? ? link_to("Download &raquo;".html_safe, @questionnaire.resume.url) : 'Not provided'
16+
= @questionnaire.resume.attached? ? link_to("Download &raquo;".html_safe, @questionnaire.resume) : 'Not provided'
1717
%p
1818
%b Traveling from:
1919
= @questionnaire.travel_not_from_school ? "Somewhere else (#{@questionnaire.travel_location})" : "My school (#{@questionnaire.school.full_name})"

app/views/manage/questionnaires/_overview.html.haml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
= @questionnaire.vcs_url? ? link_to(@questionnaire.vcs_url, @questionnaire.vcs_url, target: '_blank') : not_provided
9292
%dt.col-md-4 Resume
9393
%dd.col-md-8
94-
= @questionnaire.resume? ? link_to("Download &raquo;".html_safe, @questionnaire.resume.url) : not_provided
94+
= @questionnaire.resume.attached? ? link_to("Download &raquo;".html_safe, @questionnaire.resume) : not_provided
9595

9696
.card.mb-3
9797
.card-header Education

config/environments/production.rb

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
4040

4141
# Store uploaded files on the local file system (see config/storage.yml for options)
42-
config.active_storage.service = :local
42+
config.active_storage.service = :amazon
4343

4444
# Mount Action Cable outside main process or domain
4545
# config.action_cable.mount_path = nil
@@ -102,15 +102,4 @@
102102
mailer_url_protocol = ENV["HM_PROTOCOL"].presence || 'https'
103103
config.action_mailer.default_url_options = { host: mailer_url_host, protocol: mailer_url_protocol }
104104
config.action_mailer.asset_host = "#{mailer_url_protocol}://#{mailer_url_host}"
105-
106-
# Paperclip
107-
config.paperclip_defaults = {
108-
storage: :s3,
109-
bucket: ENV['AWS_BUCKET'],
110-
s3_credentials: {
111-
access_key_id: ENV['AWS_ACCESS_KEY_ID'],
112-
secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']
113-
},
114-
s3_region: ENV['AWS_REGION']
115-
}
116105
end

0 commit comments

Comments
 (0)