From 17cbc5785043fb6ce1cf09a3cbaed10f83823b13 Mon Sep 17 00:00:00 2001 From: wvengen Date: Fri, 17 Apr 2015 20:05:46 +0200 Subject: [PATCH] Don't error when deleting supplier/group with already existing deleted name (closes foodcoops/foodsoft#197) --- .../concerns/mark_as_deleted_with_name.rb | 25 +++++++++++++++++++ app/models/group.rb | 7 ++++-- app/models/supplier.rb | 4 ++- 3 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 app/models/concerns/mark_as_deleted_with_name.rb diff --git a/app/models/concerns/mark_as_deleted_with_name.rb b/app/models/concerns/mark_as_deleted_with_name.rb new file mode 100644 index 000000000..b5a10c5eb --- /dev/null +++ b/app/models/concerns/mark_as_deleted_with_name.rb @@ -0,0 +1,25 @@ +module MarkAsDeletedWithName + extend ActiveSupport::Concern + + def mark_as_deleted + # get maximum length of name + max_length = 100000 + if lenval = self.class.validators_on(:name).detect { |v| v.is_a?(ActiveModel::Validations::LengthValidator) } + max_length = lenval.options[:maximum] + end + # find unique deleted name + # (would have been nice to use retry, but there is no general duplicate-entry exception) + n = '' + begin + append = ' \u2020' + n + deleted_name = name.truncate(max_length-append.length, omission: '') + append + if n.blank? + n = 'A' + else + n.succ! + end + end while self.class.where(name: deleted_name).exists? + # mark as deleted + update_columns deleted_at: Time.now, name: deleted_name + end +end diff --git a/app/models/group.rb b/app/models/group.rb index f83f5beaf..fe7c98f88 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -1,6 +1,9 @@ +# encoding: utf-8 # Groups organize the User. # A Member gets the roles from the Group class Group < ActiveRecord::Base + include MarkAsDeletedWithName + has_many :memberships, dependent: :destroy has_many :users, :through => :memberships @@ -32,8 +35,8 @@ def mark_as_deleted # TODO: Checks for participating in not closed orders transaction do memberships.destroy_all - # TODO: What should happen to users? - update_column :deleted_at, Time.now + # @todo what should happen to the users? + super end end end diff --git a/app/models/supplier.rb b/app/models/supplier.rb index f9940a8a8..94db5c946 100644 --- a/app/models/supplier.rb +++ b/app/models/supplier.rb @@ -1,5 +1,7 @@ # encoding: utf-8 class Supplier < ActiveRecord::Base + include MarkAsDeletedWithName + has_many :articles, -> { where(:type => nil).includes(:article_category).order('article_categories.name', 'articles.name') } has_many :stock_articles, -> { includes(:article_category).order('article_categories.name', 'articles.name') } has_many :orders @@ -109,7 +111,7 @@ def deleted? def mark_as_deleted transaction do - update_column :deleted_at, Time.now + super articles.each(&:mark_as_deleted) end end