Skip to content

Commit 2e19096

Browse files
authored
Merge pull request #42 from sweir27/paperclip-activestorage
Migration and addition of Active Storage
2 parents b930bd2 + c2add33 commit 2e19096

File tree

7 files changed

+156
-1
lines changed

7 files changed

+156
-1
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,5 @@ public/system
2626

2727
latest.dump
2828
.env
29+
30+
storage/

config/application.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
require File.expand_path('../boot', __FILE__)
22

33
require 'rails/all'
4+
require "active_storage/engine"
45

56
# Require the gems listed in Gemfile, including any gems
67
# you've limited to :test, :development, or :production.

config/environments/production.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,6 @@
9292
},
9393
:s3_region => ENV['AWS_REGION']
9494
}
95+
96+
config.active_storage.service = :amazon
9597
end

config/storage.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
local:
2+
service: Disk
3+
root: <%= Rails.root.join("storage") %>
4+
5+
test:
6+
service: Disk
7+
root: <%= Rails.root.join("tmp/storage") %>
8+
9+
amazon:
10+
service: S3
11+
access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %>
12+
bucket: <%= ENV['S3_BUCKET_NAME'] %>
13+
region: <%= ENV['AWS_REGION'] %>
14+
secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# This migration comes from active_storage (originally 20170806125915)
2+
class CreateActiveStorageTables < ActiveRecord::Migration[5.2]
3+
def change
4+
create_table :active_storage_blobs do |t|
5+
t.string :key, null: false
6+
t.string :filename, null: false
7+
t.string :content_type
8+
t.text :metadata
9+
t.bigint :byte_size, null: false
10+
t.string :checksum, null: false
11+
t.datetime :created_at, null: false
12+
13+
t.index [ :key ], unique: true
14+
end
15+
16+
create_table :active_storage_attachments do |t|
17+
t.string :name, null: false
18+
t.references :record, null: false, polymorphic: true, index: false
19+
t.references :blob, null: false
20+
21+
t.datetime :created_at, null: false
22+
23+
t.index [ :record_type, :record_id, :name, :blob_id ], name: "index_active_storage_attachments_uniqueness", unique: true
24+
t.foreign_key :active_storage_blobs, column: :blob_id
25+
end
26+
end
27+
end
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
class ConvertToActiveStorage < ActiveRecord::Migration[5.2]
2+
require 'open-uri'
3+
4+
def up
5+
ActiveRecord::Base.connection.raw_connection.prepare("active_storage_blob_statement", <<-SQL)
6+
INSERT INTO active_storage_blobs (
7+
key, filename, content_type, metadata, byte_size, checksum, created_at
8+
) VALUES ($1, $2, $3, '{}', $4, $5, $6)
9+
SQL
10+
11+
ActiveRecord::Base.connection.raw_connection.prepare("active_storage_attachment_statement", <<-SQL)
12+
INSERT INTO active_storage_attachments (
13+
name, record_type, record_id, blob_id, created_at
14+
) VALUES ($1, $2, $3, $4, $5)
15+
SQL
16+
17+
Rails.application.eager_load!
18+
models = ActiveRecord::Base.descendants.reject(&:abstract_class?)
19+
20+
transaction do
21+
models.each do |model|
22+
attachments = model.column_names.map do |c|
23+
if c =~ /(.+)_file_name$/
24+
$1
25+
end
26+
end.compact
27+
28+
if attachments.blank?
29+
next
30+
end
31+
32+
model.find_each.each do |instance|
33+
attachments.each do |attachment|
34+
if instance.send(attachment).path.blank?
35+
next
36+
end
37+
38+
make_active_storage_records(instance, attachment, model)
39+
end
40+
end
41+
end
42+
end
43+
end
44+
45+
def down
46+
raise ActiveRecord::IrreversibleMigration
47+
end
48+
49+
private
50+
51+
def make_active_storage_records(instance, attachment, model)
52+
blob_key = key()
53+
filename = instance.send("#{attachment}_file_name")
54+
content_type = instance.send("#{attachment}_content_type")
55+
file_size = instance.send("#{attachment}_file_size")
56+
file_checksum = checksum(instance.send(attachment))
57+
created_at = instance.updated_at.iso8601
58+
59+
blob_values = [blob_key, filename, content_type, file_size, file_checksum, created_at]
60+
61+
ActiveRecord::Base.connection.raw_connection.exec_prepared(
62+
"active_storage_blob_statement",
63+
blob_values
64+
)
65+
66+
last_blob_id = ActiveStorage::Blob.last.id
67+
68+
blob_name = attachment
69+
record_type = model.name
70+
record_id = instance.id
71+
72+
attachment_values = [blob_name, record_type, record_id, last_blob_id, created_at]
73+
ActiveRecord::Base.connection.raw_connection.exec_prepared(
74+
"active_storage_attachment_statement",
75+
attachment_values
76+
)
77+
end
78+
79+
def key
80+
SecureRandom.uuid
81+
end
82+
83+
def checksum(attachment)
84+
url = attachment.url
85+
Digest::MD5.base64digest(Net::HTTP.get(URI(url)))
86+
end
87+
end

db/schema.rb

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,32 @@
1010
#
1111
# It's strongly recommended that you check this file into your version control system.
1212

13-
ActiveRecord::Schema.define(version: 2019_02_17_171348) do
13+
ActiveRecord::Schema.define(version: 2019_11_27_205244) do
1414

1515
# These are extensions that must be enabled in order to support this database
1616
enable_extension "plpgsql"
1717

18+
create_table "active_storage_attachments", force: :cascade do |t|
19+
t.string "name", null: false
20+
t.string "record_type", null: false
21+
t.bigint "record_id", null: false
22+
t.bigint "blob_id", null: false
23+
t.datetime "created_at", null: false
24+
t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id"
25+
t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true
26+
end
27+
28+
create_table "active_storage_blobs", force: :cascade do |t|
29+
t.string "key", null: false
30+
t.string "filename", null: false
31+
t.string "content_type"
32+
t.text "metadata"
33+
t.bigint "byte_size", null: false
34+
t.string "checksum", null: false
35+
t.datetime "created_at", null: false
36+
t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true
37+
end
38+
1839
create_table "announcements", id: :serial, force: :cascade do |t|
1940
t.string "title"
2041
t.text "description"
@@ -121,5 +142,6 @@
121142
t.index ["slug"], name: "index_users_on_slug"
122143
end
123144

145+
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
124146
add_foreign_key "users", "artworks", column: "primary_artwork_id", on_delete: :nullify
125147
end

0 commit comments

Comments
 (0)