Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # lib/active_record/real_delete_discreetly.rb
- module RealDeleteDiscreetly
- extend ActiveSupport::Concern
- def delete_discreetly
- relation_exist = false
- self.class.confirm_relations.each do |confirm_relation|
- if destroyed_by_association
- if destroyed_by_association.active_record == confirm_relation.to_s.classify.constantize
- relation_exist = false
- break
- end
- else
- if reflection = self.class.reflections[confirm_relation].presence
- send_method = case reflection.macro
- when :has_many
- :exists?
- else
- :present?
- end
- if send(confirm_relation).send(send_method)
- relation_exist = true
- break
- end
- else
- raise ArgumentError, "#{confirm_relation} is not Reflection"
- end
- end
- end
- unless relation_exist
- self.class.delete_all!(self.class.primary_key.to_sym => id)
- end
- end
- module ClassMethods
- def real_delete_discreetly(options = {})
- class_attribute :confirm_relations
- self.confirm_relations = options.delete(:confirm_relations)
- acts_as_paranoid options
- after_destroy :delete_discreetly
- end
- end
- end
- # spec support
- shared_examples_for 'real delete discreetly' do |opts|
- let(:base_instance) { opts[:base_instance] }
- let(:confirm_relations) { opts[:confirm_relations] }
- let(:paranoid_column) { opts[:paranoid_column] || :delete_flag }
- let(:paranoid_column_type) { opts[:paranoid_column_type] || :boolean }
- before do
- @model = base_instance.dup
- @model.save
- case paranoid_column_type.to_sym
- when :boolean
- @from = false
- @to = true
- else
- time = Time.now
- Time.stub(:now).and_return(time)
- @from = nil
- @to = time
- end
- end
- context 'relation exists' do
- before do
- confirm_relation = confirm_relations.first
- case @model.class.reflections[confirm_relation].macro
- when :has_many
- @model.send(confirm_relation).send(:build)
- else
- @model.send("build_#{confirm_relation}")
- end
- end
- it 'soft deleted' do
- expect { @model.destroy }.to change { @model.send(paranoid_column) }.from(@from).to(@to)
- end
- it 'not real deleted' do
- expect { @model.destroy }.to change(@model.class.unscoped, :count).by(0)
- end
- end
- context 'when relation not exists' do
- it 'real deleted' do
- expect { @model.destroy }.to change(@model.class.unscoped, :count).by(-1)
- end
- end
- end
- # Usage
- ## in Model
- class UserProfile < ActiveRecord::Base
- belongs_to :user
- real_delete_discreetly column: :del_flg, column_type: 'boolean', confirm_relations: [:user]
- end
- ## rspec
- require 'rails_helper'
- RSpec.describe UserProfile, type: :model do
- include_examples 'real delete discreetly',
- base_instance: UserProfile.create(user_id: nil_or_exist_id),
- confirm_relations: [:user]
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement