Advertisement
Guest User

Untitled

a guest
Mar 31st, 2015
178
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.92 KB | None | 0 0
  1. # lib/active_record/real_delete_discreetly.rb
  2. module RealDeleteDiscreetly
  3. extend ActiveSupport::Concern
  4.  
  5. def delete_discreetly
  6. relation_exist = false
  7. self.class.confirm_relations.each do |confirm_relation|
  8. if destroyed_by_association
  9. if destroyed_by_association.active_record == confirm_relation.to_s.classify.constantize
  10. relation_exist = false
  11. break
  12. end
  13. else
  14. if reflection = self.class.reflections[confirm_relation].presence
  15. send_method = case reflection.macro
  16. when :has_many
  17. :exists?
  18. else
  19. :present?
  20. end
  21.  
  22. if send(confirm_relation).send(send_method)
  23. relation_exist = true
  24. break
  25. end
  26. else
  27. raise ArgumentError, "#{confirm_relation} is not Reflection"
  28. end
  29. end
  30. end
  31.  
  32. unless relation_exist
  33. self.class.delete_all!(self.class.primary_key.to_sym => id)
  34. end
  35. end
  36.  
  37. module ClassMethods
  38. def real_delete_discreetly(options = {})
  39. class_attribute :confirm_relations
  40. self.confirm_relations = options.delete(:confirm_relations)
  41.  
  42. acts_as_paranoid options
  43. after_destroy :delete_discreetly
  44. end
  45. end
  46. end
  47.  
  48. # spec support
  49. shared_examples_for 'real delete discreetly' do |opts|
  50. let(:base_instance) { opts[:base_instance] }
  51. let(:confirm_relations) { opts[:confirm_relations] }
  52. let(:paranoid_column) { opts[:paranoid_column] || :delete_flag }
  53. let(:paranoid_column_type) { opts[:paranoid_column_type] || :boolean }
  54.  
  55. before do
  56. @model = base_instance.dup
  57. @model.save
  58. case paranoid_column_type.to_sym
  59. when :boolean
  60. @from = false
  61. @to = true
  62. else
  63. time = Time.now
  64. Time.stub(:now).and_return(time)
  65. @from = nil
  66. @to = time
  67. end
  68. end
  69.  
  70. context 'relation exists' do
  71. before do
  72. confirm_relation = confirm_relations.first
  73. case @model.class.reflections[confirm_relation].macro
  74. when :has_many
  75. @model.send(confirm_relation).send(:build)
  76. else
  77. @model.send("build_#{confirm_relation}")
  78. end
  79. end
  80.  
  81. it 'soft deleted' do
  82. expect { @model.destroy }.to change { @model.send(paranoid_column) }.from(@from).to(@to)
  83. end
  84.  
  85. it 'not real deleted' do
  86. expect { @model.destroy }.to change(@model.class.unscoped, :count).by(0)
  87. end
  88. end
  89.  
  90. context 'when relation not exists' do
  91. it 'real deleted' do
  92. expect { @model.destroy }.to change(@model.class.unscoped, :count).by(-1)
  93. end
  94. end
  95. end
  96.  
  97. # Usage
  98. ## in Model
  99. class UserProfile < ActiveRecord::Base
  100. belongs_to :user
  101. real_delete_discreetly column: :del_flg, column_type: 'boolean', confirm_relations: [:user]
  102. end
  103.  
  104. ## rspec
  105. require 'rails_helper'
  106.  
  107. RSpec.describe UserProfile, type: :model do
  108. include_examples 'real delete discreetly',
  109. base_instance: UserProfile.create(user_id: nil_or_exist_id),
  110. confirm_relations: [:user]
  111. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement