From a64cfac480e03ae6e3c035494e935ec6350fc694 Mon Sep 17 00:00:00 2001 From: Martin Ortbauer Date: Sun, 3 Mar 2024 23:12:30 -0500 Subject: [PATCH 1/4] move document data from document plugin to active storage --- db/schema.rb | 8 ++--- .../app/controllers/documents_controller.rb | 29 +++++++------------ plugins/documents/app/models/document.rb | 21 ++++++++++++-- .../app/views/documents/_form.html.haml | 2 +- 4 files changed, 34 insertions(+), 26 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 241edd291..f26201d39 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2024_04_04_004950) do +ActiveRecord::Schema[7.0].define(version: 2024_06_26_124329) do create_table "action_text_rich_texts", charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| t.string "name", null: false t.text "body", size: :long @@ -85,6 +85,7 @@ t.datetime "deleted_at", precision: nil t.string "type" t.integer "quantity", default: 0 + t.integer "max_quantity" t.index ["article_category_id"], name: "index_articles_on_article_category_id" t.index ["name", "supplier_id"], name: "index_articles_on_name_and_supplier_id" t.index ["supplier_id"], name: "index_articles_on_supplier_id" @@ -101,7 +102,7 @@ create_table "bank_accounts", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| t.string "name", null: false t.string "iban" - t.string "description" + t.text "description" t.decimal "balance", precision: 12, scale: 2, default: "0.0", null: false t.datetime "last_import", precision: nil t.string "import_continuation_point" @@ -131,12 +132,11 @@ create_table "documents", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| t.string "name" - t.string "mime" - t.binary "data", size: :long t.integer "created_by_user_id" t.datetime "created_at", precision: nil t.datetime "updated_at", precision: nil t.integer "parent_id" + t.boolean "folder", default: false, null: false t.index ["parent_id"], name: "index_documents_on_parent_id" end diff --git a/plugins/documents/app/controllers/documents_controller.rb b/plugins/documents/app/controllers/documents_controller.rb index 8950f3471..e08d79654 100644 --- a/plugins/documents/app/controllers/documents_controller.rb +++ b/plugins/documents/app/controllers/documents_controller.rb @@ -6,13 +6,13 @@ class DocumentsController < ApplicationController def index sort = if params['sort'] case params['sort'] - when 'name' then 'data IS NULL DESC, name' + when 'name' then 'folder DESC, name' when 'created_at' then 'created_at' - when 'name_reverse' then 'data IS NULL, name DESC' + when 'name_reverse' then 'folder, name DESC' when 'created_at_reverse' then 'created_at DESC' end else - 'data IS NULL DESC, name' + 'folder DESC, name' end sort = Arel.sql(sort) # this is okay as we don't use user params directly @documents = Document.where(parent: @document).page(params[:page]).per(@per_page).order(sort) @@ -20,24 +20,21 @@ def index def new @document = Document.new parent_id: params[:document_id] - @document.mime = '' unless params[:type] == 'folder' + @document.folder = params[:type] == 'folder' end def create @document = Document.new name: params[:document][:name] @document.parent = Document.find_by_id(params[:document][:parent_id]) - data = params[:document][:data] - if data - @document.data = data.read - @document.mime = FileMagic.new(FileMagic::MAGIC_MIME).buffer(@document.data) - raise t('.not_allowed_mime', mime: @document.mime) unless allowed_mime? @document.mime - + @document.attachment = params[:document][:attachment] + if !@document.attachment.nil? if @document.name.empty? - name = File.basename(data.original_filename) + name = File.basename(@document.attachment.filename.to_s) @document.name = name.gsub(/[^\w.-]/, '_') end end @document.created_by = current_user + @document.folder = !params[:document].has_key?(:attachment) @document.save! redirect_to @document.parent || documents_path, notice: t('.notice') rescue StandardError => e @@ -55,6 +52,7 @@ def update def destroy @document = Document.find(params[:id]) if @document.created_by == current_user or current_user.role_admin? + @document.delete_attachment @document.destroy redirect_to documents_path, notice: t('.notice') else @@ -67,7 +65,7 @@ def destroy def show @document = Document.find(params[:id]) if @document.file? - send_data(@document.data, filename: @document.filename, type: @document.mime) + send_data(@document.attachment.download, filename: @document.name, type: @document.attachment.blob.content_type) else index render :index @@ -78,11 +76,4 @@ def move @document = Document.find(params[:document_id]) end - def allowed_mime?(mime) - whitelist = FoodsoftConfig[:documents_allowed_extension].split - MIME::Types.type_for(whitelist).each do |type| - return true if type.like? mime - end - false - end end diff --git a/plugins/documents/app/models/document.rb b/plugins/documents/app/models/document.rb index 38608bfdc..1a4c8da00 100644 --- a/plugins/documents/app/models/document.rb +++ b/plugins/documents/app/models/document.rb @@ -4,14 +4,18 @@ class Document < ApplicationRecord belongs_to :created_by, class_name: 'User', foreign_key: 'created_by_user_id' + has_one_attached :attachment + acts_as_tree + validate :valid_attachment + def file? !folder? end - def folder? - mime.nil? + def valid_attachment + errors.add(:attachment, I18n.t('documents.create.not_allowed_mime', mime: attachment.content_type)) unless !attachment.attached? or allowed_mime? attachment.content_type end def filename @@ -27,4 +31,17 @@ def filename "#{name}.#{types.first.preferred_extension}" end + + def allowed_mime?(mime) + whitelist = FoodsoftConfig[:documents_allowed_extension].split + MIME::Types.type_for(whitelist).each do |type| + return true if type.like? mime + end + false + end + + def delete_attachment + attachment.purge_later + end + end diff --git a/plugins/documents/app/views/documents/_form.html.haml b/plugins/documents/app/views/documents/_form.html.haml index 68b4acd24..cae2e507f 100644 --- a/plugins/documents/app/views/documents/_form.html.haml +++ b/plugins/documents/app/views/documents/_form.html.haml @@ -6,7 +6,7 @@ .modal-body = f.input :name, as: :string, required: @document.folder? - if @document.file? - = f.input :data, as: :file, required: true + = f.input :attachment, as: :file, input_html: {multiple: false}, direct_upload: true, required: true .modal-footer = link_to t('ui.close'), '#', class: 'btn', data: {dismiss: 'modal'} = f.submit t('.submit'), class: 'btn btn-primary' From e643c154c94cd26e3273e7b0afd574b59727c672 Mon Sep 17 00:00:00 2001 From: Martin Ortbauer Date: Tue, 5 Mar 2024 08:39:53 -0500 Subject: [PATCH 2/4] implement rubocoop recommendations --- .../documents/app/controllers/documents_controller.rb | 11 ++++------- plugins/documents/app/models/document.rb | 3 +-- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/plugins/documents/app/controllers/documents_controller.rb b/plugins/documents/app/controllers/documents_controller.rb index e08d79654..246acb607 100644 --- a/plugins/documents/app/controllers/documents_controller.rb +++ b/plugins/documents/app/controllers/documents_controller.rb @@ -27,14 +27,12 @@ def create @document = Document.new name: params[:document][:name] @document.parent = Document.find_by_id(params[:document][:parent_id]) @document.attachment = params[:document][:attachment] - if !@document.attachment.nil? - if @document.name.empty? - name = File.basename(@document.attachment.filename.to_s) - @document.name = name.gsub(/[^\w.-]/, '_') - end + if !@document.attachment.nil? and @document.name.empty? + name = File.basename(@document.attachment.filename.to_s) + @document.name = name.gsub(/[^\w.-]/, '_') end @document.created_by = current_user - @document.folder = !params[:document].has_key?(:attachment) + @document.folder = !params[:document].key?(:attachment) @document.save! redirect_to @document.parent || documents_path, notice: t('.notice') rescue StandardError => e @@ -75,5 +73,4 @@ def show def move @document = Document.find(params[:document_id]) end - end diff --git a/plugins/documents/app/models/document.rb b/plugins/documents/app/models/document.rb index 1a4c8da00..fe10e6ba1 100644 --- a/plugins/documents/app/models/document.rb +++ b/plugins/documents/app/models/document.rb @@ -15,7 +15,7 @@ def file? end def valid_attachment - errors.add(:attachment, I18n.t('documents.create.not_allowed_mime', mime: attachment.content_type)) unless !attachment.attached? or allowed_mime? attachment.content_type + errors.add(:attachment, I18n.t('documents.create.not_allowed_mime', mime: attachment.content_type)) unless !attachment.attached? || allowed_mime?(attachment.content_type) end def filename @@ -43,5 +43,4 @@ def allowed_mime?(mime) def delete_attachment attachment.purge_later end - end From 1a81f9fc237b6d76c2cecd748a0c27cd13a62b2c Mon Sep 17 00:00:00 2001 From: Philipp Rothmann Date: Wed, 6 Mar 2024 16:06:42 +0100 Subject: [PATCH 3/4] add migration --- db/schema.rb | 4 ++ ...141647_move_documents_to_active_storage.rb | 45 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 plugins/documents/db/migrate/20240306141647_move_documents_to_active_storage.rb diff --git a/db/schema.rb b/db/schema.rb index f26201d39..554718f3d 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,11 @@ # # It's strongly recommended that you check this file into your version control system. +<<<<<<< HEAD ActiveRecord::Schema[7.0].define(version: 2024_06_26_124329) do +======= +ActiveRecord::Schema[7.0].define(version: 2024_03_06_141647) do +>>>>>>> c2298680 (add migration) create_table "action_text_rich_texts", charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| t.string "name", null: false t.text "body", size: :long diff --git a/plugins/documents/db/migrate/20240306141647_move_documents_to_active_storage.rb b/plugins/documents/db/migrate/20240306141647_move_documents_to_active_storage.rb new file mode 100644 index 000000000..95f5559d6 --- /dev/null +++ b/plugins/documents/db/migrate/20240306141647_move_documents_to_active_storage.rb @@ -0,0 +1,45 @@ +class MoveDocumentsToActiveStorage < ActiveRecord::Migration[7.0] + def up + change_table :documents do |t| + t.boolean :folder, default: false, null: false + end + + Document.find_each do |document| + if document.data.present? && document.mime.present? + document.attachment.attach(create_blob_from_document(document)) + else + document.update(folder: true) + end + end + + change_table :documents, bulk: true do |t| + t.remove :data + t.remove :mime + end + end + + def down + change_table :documents, bulk: true do |t| + t.binary :data, limit: 16.megabyte + t.string :mime + t.remove :folder + end + + Document.find_each do |document| + next unless document.attachment.attached? + + document.update( + data: document.attachment.download, + mime: document.attachment.blob.content_type + ) + end + end + + def create_blob_from_document(document) + ActiveStorage::Blob.create_and_upload!( + io: StringIO.new(document.data), + filename: document.name, + content_type: document.mime + ) + end +end From 2cb636dca49c9808b5f6c5d9bc44d90f47d7baf4 Mon Sep 17 00:00:00 2001 From: Philipp Rothmann Date: Wed, 6 Mar 2024 16:06:42 +0100 Subject: [PATCH 4/4] add migration to standard as documents plugin is enabled by default --- ...141647_move_documents_to_active_storage.rb | 45 +++++++++++++++++++ db/schema.rb | 4 -- 2 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 db/migrate/20240306141647_move_documents_to_active_storage.rb diff --git a/db/migrate/20240306141647_move_documents_to_active_storage.rb b/db/migrate/20240306141647_move_documents_to_active_storage.rb new file mode 100644 index 000000000..95f5559d6 --- /dev/null +++ b/db/migrate/20240306141647_move_documents_to_active_storage.rb @@ -0,0 +1,45 @@ +class MoveDocumentsToActiveStorage < ActiveRecord::Migration[7.0] + def up + change_table :documents do |t| + t.boolean :folder, default: false, null: false + end + + Document.find_each do |document| + if document.data.present? && document.mime.present? + document.attachment.attach(create_blob_from_document(document)) + else + document.update(folder: true) + end + end + + change_table :documents, bulk: true do |t| + t.remove :data + t.remove :mime + end + end + + def down + change_table :documents, bulk: true do |t| + t.binary :data, limit: 16.megabyte + t.string :mime + t.remove :folder + end + + Document.find_each do |document| + next unless document.attachment.attached? + + document.update( + data: document.attachment.download, + mime: document.attachment.blob.content_type + ) + end + end + + def create_blob_from_document(document) + ActiveStorage::Blob.create_and_upload!( + io: StringIO.new(document.data), + filename: document.name, + content_type: document.mime + ) + end +end diff --git a/db/schema.rb b/db/schema.rb index 554718f3d..f26201d39 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,11 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -<<<<<<< HEAD ActiveRecord::Schema[7.0].define(version: 2024_06_26_124329) do -======= -ActiveRecord::Schema[7.0].define(version: 2024_03_06_141647) do ->>>>>>> c2298680 (add migration) create_table "action_text_rich_texts", charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| t.string "name", null: false t.text "body", size: :long