Last active
November 2, 2022 15:29
-
-
Save dabit/c8c06f0b2fc51219dd6691bf6306a6e0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ApplicationRecord < ActiveRecord::Base | |
primary_abstract_class | |
def self.inherited(subclass) | |
super | |
return unless subclass.has_attribute?(:deleted_at) | |
setup_for_soft_delete(subclass) | |
rescue ActiveRecord::NoDatabaseError, ActiveRecord::StatementInvalid, ActiveRecord::ConnectionNotEstablished | |
nil | |
end | |
def self.setup_for_soft_delete(subclass) | |
subclass.send(:default_scope, -> { where(deleted_at: nil) }) | |
class << subclass | |
def archived | |
where.not(deleted_at: nil) | |
end | |
end | |
subclass.define_method(:destroy) do | |
touch(:deleted_at) | |
end | |
end | |
def self.human_enum_name(enum_name, enum_value) | |
I18n.t("activerecord.attributes.#{model_name.i18n_key}.#{enum_name.to_s.pluralize}.#{enum_value}") | |
end | |
def self.plural_name | |
model_name.human(count: 2) | |
end | |
def self.enum_collection_for_select(enum_plural_name) | |
send(enum_plural_name).collect { |k, _v| [k, human_enum_name(enum_plural_name, k)] } | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@alejandrodevs My use case is very simple and straightforward; I just want to keep a small selection of tables where I want the data to be deleted but still keep it handy in case someone needs it back. I have been in several situations where the user deletes a record by mistake or simply because they thought they would not need it in the future and then realize that they do, in fact, need it later.
I use the default scope because I don't expect this data to show up anywhere within the app, and I want it to behave as if it's gone forever. I rarely add the functionality to browse this data. I include an
archived
scope for my convenience, just in case I want to dig through it via the console.Adding a
deleted_at
column is explicit enough to tell me if a table is soft deletable or not (I religiously use annotate, so I can always see what my tables look like).I override
destroy
because it makes it simpler to turn it on and off just by adding or removing thedeleted_at
column.By the way, I will include your scope-based refactoring in a future iteration; thank you for that. I agree that using
scope
is better.Lastly, I understand there are gems for everything these days, but I personally never add a dependency for something I can fix with a few lines of code.