diff --git a/.gitignore b/.gitignore index ed3c95a..853c518 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ !/tmp/pids/ !/tmp/pids/.keep +/storage /public/assets .byebug_history diff --git a/Gemfile b/Gemfile index ff3396f..b169662 100644 --- a/Gemfile +++ b/Gemfile @@ -37,6 +37,7 @@ gem 'devise_ldap_authenticatable' gem 'net-ldap' # Utilities +gem "image_processing", "~> 1.12.2" gem "rqrcode", "~> 2.0" gem 'rails-settings-cached', '~> 2.8.3' gem 'pagy', '~> 6.0', '>= 6.0.2' diff --git a/Gemfile.lock b/Gemfile.lock index 04c1e55..b869deb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -182,6 +182,9 @@ GEM hashdiff (1.0.1) i18n (1.14.1) concurrent-ruby (~> 1.0) + image_processing (1.12.2) + mini_magick (>= 4.9.5, < 5) + ruby-vips (>= 2.0.17, < 3) importmap-rails (1.1.6) actionpack (>= 6.0.0) railties (>= 6.0.0) @@ -220,6 +223,7 @@ GEM marcel (1.0.2) matrix (0.4.2) method_source (1.0.0) + mini_magick (4.12.0) mini_mime (1.1.2) minitest (5.18.0) multipart-post (2.3.0) @@ -337,6 +341,8 @@ GEM rubocop-ast (1.29.0) parser (>= 3.2.1.0) ruby-progressbar (1.13.0) + ruby-vips (2.1.4) + ffi (~> 1.12) ruby2_keywords (0.0.5) rufus-scheduler (3.9.1) fugit (~> 1.1, >= 1.1.6) @@ -435,6 +441,7 @@ DEPENDENCIES flipper flipper-active_record flipper-ui + image_processing (~> 1.12.2) importmap-rails jbuilder (~> 2.7) letter_opener diff --git a/config/application.rb b/config/application.rb index c701f24..fe0be55 100644 --- a/config/application.rb +++ b/config/application.rb @@ -5,7 +5,7 @@ require "rails" require "active_model/railtie" require "active_job/railtie" require "active_record/railtie" -# require "active_storage/engine" +require "active_storage/engine" require "action_controller/railtie" require "action_mailer/railtie" require "action_mailbox/engine" diff --git a/config/environments/development.rb b/config/environments/development.rb index b7d1659..eecc942 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -70,4 +70,7 @@ Rails.application.configure do # Allow requests from any IP config.web_console.whiny_requests = false + + # Store attachments on the local disk (in ./storage) + config.active_storage.service = :local end diff --git a/config/environments/production.rb b/config/environments/production.rb index c51028f..bfcfecb 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -110,6 +110,10 @@ Rails.application.configure do # Set this to true and configure the email server for immediate delivery to raise delivery errors. config.action_mailer.raise_delivery_errors = true + # TODO make configurable + # Store attachments in S3-compatible back-end + config.active_storage.service = :local + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to # the I18n.default_locale when a translation cannot be found). config.i18n.fallbacks = true diff --git a/config/environments/test.rb b/config/environments/test.rb index f3c0b8f..739a1ac 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -51,4 +51,7 @@ Rails.application.configure do } config.active_job.queue_adapter = :test + + # Store attachments on the local disk (in ./tmp) + config.active_storage.service = :test end diff --git a/config/storage.yml b/config/storage.yml index 695f17b..1f93f73 100644 --- a/config/storage.yml +++ b/config/storage.yml @@ -1,7 +1,7 @@ -test: - service: Disk - root: <%= Rails.root.join("tmp/storage") %> - local: service: Disk root: <%= Rails.root.join("storage") %> + +test: + service: Disk + root: <%= Rails.root.join("tmp/storage") %> diff --git a/db/migrate/20230906073324_create_active_storage_tables.active_storage.rb b/db/migrate/20230906073324_create_active_storage_tables.active_storage.rb new file mode 100644 index 0000000..8a7bfe1 --- /dev/null +++ b/db/migrate/20230906073324_create_active_storage_tables.active_storage.rb @@ -0,0 +1,57 @@ +# This migration comes from active_storage (originally 20170806125915) +class CreateActiveStorageTables < ActiveRecord::Migration[5.2] + 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 :active_storage_blobs, id: primary_key_type do |t| + t.string :key, null: false + t.string :filename, null: false + t.string :content_type + t.text :metadata + t.string :service_name, null: false + t.bigint :byte_size, null: false + t.string :checksum + + if connection.supports_datetime_with_precision? + t.datetime :created_at, precision: 6, null: false + else + t.datetime :created_at, null: false + end + + t.index [ :key ], unique: true + end + + create_table :active_storage_attachments, id: primary_key_type do |t| + t.string :name, null: false + t.references :record, null: false, polymorphic: true, index: false, type: foreign_key_type + t.references :blob, null: false, type: foreign_key_type + + if connection.supports_datetime_with_precision? + t.datetime :created_at, precision: 6, null: false + else + t.datetime :created_at, null: false + end + + t.index [ :record_type, :record_id, :name, :blob_id ], name: :index_active_storage_attachments_uniqueness, unique: true + t.foreign_key :active_storage_blobs, column: :blob_id + end + + create_table :active_storage_variant_records, id: primary_key_type do |t| + t.belongs_to :blob, null: false, index: false, type: foreign_key_type + t.string :variation_digest, null: false + + t.index [ :blob_id, :variation_digest ], name: :index_active_storage_variant_records_uniqueness, unique: true + t.foreign_key :active_storage_blobs, column: :blob_id + 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 diff --git a/db/schema.rb b/db/schema.rb index bdb7cd6..bff7e78 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,35 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2023_05_23_120753) do +ActiveRecord::Schema[7.0].define(version: 2023_09_06_073324) do + create_table "active_storage_attachments", force: :cascade do |t| + t.string "name", null: false + t.string "record_type", null: false + t.bigint "record_id", null: false + t.bigint "blob_id", null: false + t.datetime "created_at", null: false + t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id" + t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true + end + + create_table "active_storage_blobs", force: :cascade do |t| + t.string "key", null: false + t.string "filename", null: false + t.string "content_type" + t.text "metadata" + t.string "service_name", null: false + t.bigint "byte_size", null: false + t.string "checksum" + t.datetime "created_at", null: false + t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true + end + + create_table "active_storage_variant_records", force: :cascade do |t| + t.bigint "blob_id", null: false + t.string "variation_digest", null: false + t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true + end + create_table "donations", force: :cascade do |t| t.integer "user_id" t.integer "amount_sats" @@ -94,5 +122,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_05_23_120753) do t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true end + add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id" + add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" add_foreign_key "remote_storage_authorizations", "users" end