aboutsummaryrefslogtreecommitdiffstats
path: root/lib/active_vault
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2017-07-05 15:18:50 +0200
committerDavid Heinemeier Hansson <david@loudthinking.com>2017-07-05 15:18:50 +0200
commitaaf841518866b34d769d9a951a389d1eef70d6e7 (patch)
tree81456d39a3654247196ce4cbd6bab8ab356aa0f6 /lib/active_vault
parent97aa328bb1e9d43bba1bcae2c8ddbaed397770c0 (diff)
downloadrails-aaf841518866b34d769d9a951a389d1eef70d6e7.tar.gz
rails-aaf841518866b34d769d9a951a389d1eef70d6e7.tar.bz2
rails-aaf841518866b34d769d9a951a389d1eef70d6e7.zip
Add attachments
Diffstat (limited to 'lib/active_vault')
-rw-r--r--lib/active_vault/attachment.rb27
-rw-r--r--lib/active_vault/attachments.rb30
-rw-r--r--lib/active_vault/migration.rb27
-rw-r--r--lib/active_vault/railtie.rb8
4 files changed, 85 insertions, 7 deletions
diff --git a/lib/active_vault/attachment.rb b/lib/active_vault/attachment.rb
new file mode 100644
index 0000000000..eb108e9cbb
--- /dev/null
+++ b/lib/active_vault/attachment.rb
@@ -0,0 +1,27 @@
+require "active_vault/blob"
+require "global_id"
+require "active_support/core_ext/module/delegation"
+
+# Schema: id, record_gid, blob_id, created_at
+class ActiveVault::Attachment < ActiveRecord::Base
+ self.table_name = "active_vault_attachments"
+
+ belongs_to :blob, class_name: "ActiveVault::Blob"
+
+ delegate_missing_to :blob
+
+ def record
+ @record ||= GlobalID::Locator.locate(record_gid)
+ end
+
+ def record=(record)
+ @record = record
+ self.record_gid = record&.to_gid
+ end
+
+ def purge
+ blob.purge
+ destroy
+ record.public_send "#{name}=", nil
+ end
+end
diff --git a/lib/active_vault/attachments.rb b/lib/active_vault/attachments.rb
new file mode 100644
index 0000000000..c66c142650
--- /dev/null
+++ b/lib/active_vault/attachments.rb
@@ -0,0 +1,30 @@
+require "active_vault/attachment"
+require "action_dispatch/http/upload"
+
+module ActiveVault::Attachments
+ def has_file(name)
+ define_method(name) do
+ (@active_vault_attachments ||= {})[name] ||=
+ ActiveVault::Attachment.find_by(record_gid: to_gid.to_s, name: name)&.tap { |a| a.record = self }
+ end
+
+ define_method(:"#{name}=") do |attachable|
+ case attachable
+ when ActiveVault::Blob
+ blob = attachable
+ when ActionDispatch::Http::UploadedFile
+ blob = ActiveVault::Blob.create_after_upload! \
+ io: attachable.open,
+ filename: attachable.original_filename,
+ content_type: attachable.content_type
+ when Hash
+ blob = ActiveVault::Blob.create_after_upload!(attachable)
+ when NilClass
+ blob = nil
+ end
+
+ (@active_vault_attachments ||= {})[name] = blob ?
+ ActiveVault::Attachment.create!(record_gid: to_gid.to_s, name: name, blob: blob)&.tap { |a| a.record = self } : nil
+ end
+ end
+end
diff --git a/lib/active_vault/migration.rb b/lib/active_vault/migration.rb
index b3c66428ce..985d26d1b9 100644
--- a/lib/active_vault/migration.rb
+++ b/lib/active_vault/migration.rb
@@ -1,15 +1,28 @@
-class ActiveVault::CreateBlobs < ActiveRecord::Migration[5.1]
+class ActiveVault::CreateTables < ActiveRecord::Migration[5.1]
def change
- t.string :key
- t.string :filename
- t.string :content_type
- t.text :metadata
create_table :active_vault_blobs do |t|
+ t.string :key
+ t.string :filename
+ t.string :content_type
+ t.text :metadata
t.integer :byte_size
- t.string :checksum
- t.time :created_at
+ t.string :checksum
+ t.time :created_at
t.index [ :key ], unique: true
end
+
+ create_table :active_vault_attachments do |t|
+ t.string :name
+ t.string :record_gid
+ t.integer :blob_id
+
+ t.time :created_at
+
+ t.index :record_gid
+ t.index :blob_id
+ t.index [ :record_gid, :name ]
+ t.index [ :record_gid, :blob_id ], unique: true
+ end
end
end
diff --git a/lib/active_vault/railtie.rb b/lib/active_vault/railtie.rb
index c254f4c77c..f1c5740aa5 100644
--- a/lib/active_vault/railtie.rb
+++ b/lib/active_vault/railtie.rb
@@ -15,5 +15,13 @@ module ActiveVault
end
end
end
+
+ initializer "action_file.attachments" do
+ require "active_vault/attachments"
+
+ ActiveSupport.on_load(:active_record) do
+ extend ActiveVault::Attachments
+ end
+ end
end
end