Skip to content

Commit

Permalink
Merge branch 'core' into update-method-call-test-for-has-many-through…
Browse files Browse the repository at this point in the history
…-relationship
  • Loading branch information
mathieujobin authored Sep 3, 2024
2 parents 4878b30 + f441c37 commit 5b4078c
Show file tree
Hide file tree
Showing 8 changed files with 224 additions and 65 deletions.
47 changes: 13 additions & 34 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,45 +15,24 @@ jobs:
strategy:
fail-fast: false
matrix:
ruby:
- 3.1
- '3.0'
- 2.7
- 2.6
- 2.5
# - jruby-9.2.19.0
# - jruby-9.3.1.0
rails:
- '~> 5.1.0'
- '~> 5.2.0'
- '~> 6.0.0'
- '~> 6.1.0'
- '~> 7.0.0'
- 'edge'
rails: ["edge", "~> 7.2.0", "~> 7.1.0", "~> 7.0.0", "~> 6.1.0"]
ruby: ["3.3","3.2", "3.1", "3.0", "2.7"]
exclude:
# Rails edge is now 7.x and requires ruby 2.7
- rails: 'edge'
ruby: 2.6
- rails: 'edge'
ruby: 2.5
- rails: '~> 7.0.0'
ruby: 2.6
- rails: '~> 7.0.0'
ruby: 2.5
# Legacy Rails with newer rubies
- rails: '~> 5.1.0'
ruby: '3.0'
- rails: '~> 5.2.0'
ruby: '3.0'
- rails: '~> 5.1.0'
ruby: 3.1
- rails: '~> 5.2.0'
ruby: 3.1
- rails: "~> 7.2.0"
ruby: "3.0"
- rails: "~> 7.2.0"
ruby: "2.7"
- rails: "edge"
ruby: "3.0"
- rails: "edge"
ruby: "2.7"



env:
RAILS: ${{ matrix.rails }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
Expand Down
39 changes: 39 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,44 @@
# paranoia Changelog

## 3.0.0 - August 13, 2024

_Tagged as 3.0 as Ruby + Rails version constraints have been modernised._

- [#564](https://github.com/rubysherpas/paranoia/pull/564) Support Rails edge
- [#563](https://github.com/rubysherpas/paranoia/pull/563) Support Rails 7.2

## 2.6.4 - July 20, 2024

* [#554](https://github.com/rubysherpas/paranoia/pull/554) Support prebuilt counter cache association list (#554)
[Joé Dupuis](https://github.com/JoeDupuis)
* [#551](https://github.com/rubysherpas/paranoia/pull/551) Fix: restore has_one with scope (#551)
[Paweł Charyło](https://github.com/zygzagZ)
* [#555](https://github.com/rubysherpas/paranoia/pull/555) 📝 Add Yard documentation for Paranoia::Query (#555)
[Clément Prod'homme](https://github.com/cprodhomme)

## 2.6.3 - Oct 12, 2023

* [#548](https://github.com/rubysherpas/paranoia/pull/548) Add support for [Rails 7.1](https://github.com/rails/rails/releases/tag/v7.1.0) (#548)
[Indyarocks](https://github.com/indyarocks)

## 2.6.2 - Jun 6, 2023

* [#441](https://github.com/rubysherpas/paranoia/pull/441) Recursive restore with has_many/one through assocs (#441)
[Emil Ong](https://github.com/emilong)

## 2.6.1 - Nov 16, 2022

* [#535](https://github.com/rubysherpas/paranoia/pull/535) Allow to skip updating paranoia_destroy_attributes for records while really_destroy!
[Anton Bogdanov](https://github.com/kortirso)

## 2.6.0 - Mar 23, 2022

* [#512](https://github.com/rubysherpas/paranoia/pull/512) Quote table names; Mysql 8 has keywords that might match table names which cause an exception.
* [#476](https://github.com/rubysherpas/paranoia/pull/476) Fix syntax error in documentation.
* [#485](https://github.com/rubysherpas/paranoia/pull/485) Rollback transaction if destroy aborted.
* [#522](https://github.com/rubysherpas/paranoia/pull/522) Add failing tests for association with abort on destroy.
* [#513](https://github.com/rubysherpas/paranoia/pull/513) Fix create callback called on destroy.

## 2.5.3

* [#532](https://github.com/rubysherpas/paranoia/pull/532) Fix: correct bug when sentinel_value is not a timestamp
Expand Down
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ sqlite = ENV['SQLITE_VERSION']
if sqlite
gem 'sqlite3', sqlite, platforms: [:ruby]
else
gem 'sqlite3', platforms: [:ruby]
gem 'sqlite3', '~> 1.4', platforms: [:ruby]
end

platforms :jruby do
Expand Down
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[![Gem Version](https://badge.fury.io/rb/paranoia.svg)](https://badge.fury.io/rb/paranoia)
[![build](https://github.com/rubysherpas/paranoia/actions/workflows/build.yml/badge.svg)](https://github.com/rubysherpas/paranoia/actions/workflows/build.yml)

**Notice:**
**Notice:**

`paranoia` has some surprising behaviour (like overriding ActiveRecord's `delete` and `destroy`) and is not recommended for new projects. See [`discard`'s README](https://github.com/jhawthorn/discard#why-not-paranoia-or-acts_as_paranoid) for more details.

Expand Down Expand Up @@ -103,6 +103,14 @@ If you really want it gone *gone*, call `really_destroy!`:
# => client
```

If you need skip updating timestamps for deleting records, call `really_destroy!(update_destroy_attributes: false)`.
When we call `really_destroy!(update_destroy_attributes: false)` on the parent `client`, then each child `email` will also have `really_destroy!(update_destroy_attributes: false)` called.

``` ruby
>> client.really_destroy!(update_destroy_attributes: false)
# => client
```

If you want to use a column other than `deleted_at`, you can pass it as an option:

``` ruby
Expand Down
61 changes: 41 additions & 20 deletions lib/paranoia.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ def self.included(klazz)
module Query
def paranoid? ; true ; end

# If you want to find all records, even those which are deleted
def with_deleted
if ActiveRecord::VERSION::STRING >= "4.1"
return unscope where: paranoia_column
end
all.tap { |x| x.default_scoped = false }
end

# If you want to find only the deleted records
def only_deleted
if paranoia_sentinel_value.nil?
return with_deleted.where.not(paranoia_column => paranoia_sentinel_value)
Expand All @@ -45,6 +47,7 @@ def only_deleted
end
alias_method :deleted, :only_deleted

# If you want to restore a record
def restore(id_or_ids, opts = {})
ids = Array(id_or_ids).flatten
any_object_instead_of_id = ids.any? { |id| ActiveRecord::Base === id }
Expand Down Expand Up @@ -100,7 +103,7 @@ def paranoia_update!(attributes)
def paranoia_destroy
with_transaction_returning_status do
result = run_callbacks(:destroy) do
@_disable_counter_cache = deleted?
@_disable_counter_cache = paranoia_destroyed?
result = paranoia_delete
next result unless result && ActiveRecord::VERSION::STRING >= '4.2'
each_counter_cached_associations do |association|
Expand All @@ -113,7 +116,7 @@ def paranoia_destroy
@_disable_counter_cache = false
result
end
raise ActiveRecord::Rollback, "Not destroyed" unless self.deleted?
raise ActiveRecord::Rollback, "Not destroyed" unless paranoia_destroyed?
result
end || false
end
Expand Down Expand Up @@ -184,7 +187,7 @@ def paranoia_destroyed?
end
alias :deleted? :paranoia_destroyed?

def really_destroy!
def really_destroy!(update_destroy_attributes: true)
with_transaction_returning_status do
run_callbacks(:real_destroy) do
@_disable_counter_cache = paranoia_destroyed?
Expand All @@ -198,21 +201,40 @@ def really_destroy!
# .paranoid? will work for both instances and classes
next unless association_data && association_data.paranoid?
if reflection.collection?
next association_data.with_deleted.each(&:really_destroy!)
next association_data.with_deleted.find_each { |record|
record.really_destroy!(update_destroy_attributes: update_destroy_attributes)
}
end
association_data.really_destroy!
association_data.really_destroy!(update_destroy_attributes: update_destroy_attributes)
end
end
update_columns(paranoia_destroy_attributes)
update_columns(paranoia_destroy_attributes) if update_destroy_attributes
destroy_without_paranoia
end
end
end

private

def counter_cache_disabled?
defined?(@_disable_counter_cache) && @_disable_counter_cache
end

def counter_cached_association_names
return [] if counter_cache_disabled?
super
end

def each_counter_cached_associations
!(defined?(@_disable_counter_cache) && @_disable_counter_cache) ? super : []
return [] if counter_cache_disabled?

if defined?(super)
super
else
counter_cached_association_names.each do |name|
yield association(name)
end
end
end

def paranoia_restore_attributes
Expand All @@ -231,6 +253,16 @@ def timestamp_attributes_with_current_time
timestamp_attributes_for_update_in_model.each_with_object({}) { |attr,hash| hash[attr] = current_time_from_proper_timezone }
end

def paranoia_find_has_one_target(association)
association_foreign_key = association.options[:through].present? ? association.klass.primary_key : association.foreign_key
association_find_conditions = { association_foreign_key => self.id }
association_find_conditions[association.type] = self.class.name if association.type

scope = association.klass.only_deleted.where(association_find_conditions)
scope = scope.merge(association.scope) if association.scope
scope.first
end

# restore associated records that have been soft deleted when
# we called #destroy
def restore_associated_records(recovery_window_range = nil)
Expand All @@ -254,19 +286,8 @@ def restore_associated_records(recovery_window_range = nil)
end

if association_data.nil? && association.macro.to_s == "has_one"
association_class_name = association.klass.name
association_foreign_key = association.foreign_key

if association.type
association_polymorphic_type = association.type
association_find_conditions = { association_polymorphic_type => self.class.name.to_s, association_foreign_key => self.id }
else
association_find_conditions = { association_foreign_key => self.id }
end

association_class = association_class_name.constantize
if association_class.paranoid?
association_class.only_deleted.where(association_find_conditions).first
if association.klass.paranoid?
paranoia_find_has_one_target(association)
.try!(:restore, recursive: true, :recovery_window_range => recovery_window_range)
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/paranoia/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Paranoia
VERSION = '2.5.3'.freeze
VERSION = '3.0.0'.freeze
end
6 changes: 3 additions & 3 deletions paranoia.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Gem::Specification.new do |s|
s.license = 'MIT'
s.summary = "Paranoia is a re-implementation of acts_as_paranoid for Rails 3, 4, and 5, using much, much, much less code."
s.description = <<-DSC
Paranoia is a re-implementation of acts_as_paranoid for Rails 4, 5, 6, and 7,
Paranoia is a re-implementation of acts_as_paranoid for Rails 5, 6, and 7,
using much, much, much less code. You would use either plugin / gem if you
wished that when you called destroy on an Active Record object that it
didn't actually destroy it, but just "hid" the record. Paranoia does this
Expand All @@ -22,9 +22,9 @@ Gem::Specification.new do |s|

s.required_rubygems_version = ">= 1.3.6"

s.required_ruby_version = '>= 2.5'
s.required_ruby_version = '>= 2.7'

s.add_dependency 'activerecord', '>= 5.1', '< 7.1'
s.add_dependency 'activerecord', '>= 6', '< 8.1'

s.add_development_dependency "bundler", ">= 1.0.0"
s.add_development_dependency "rake"
Expand Down
Loading

0 comments on commit 5b4078c

Please sign in to comment.