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 Mar 23, 2022
2 parents 8a004ca + cc19cef commit 4878b30
Show file tree
Hide file tree
Showing 10 changed files with 397 additions and 76 deletions.
61 changes: 61 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby

name: build

on: [push, pull_request]

jobs:
test:
runs-on: ubuntu-20.04
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'
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

env:
RAILS: ${{ matrix.rails }}
steps:
- uses: actions/checkout@v2
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
- run: bundle exec rake
28 changes: 0 additions & 28 deletions .travis.yml

This file was deleted.

54 changes: 54 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,59 @@
# paranoia Changelog

## 2.5.3

* [#532](https://github.com/rubysherpas/paranoia/pull/532) Fix: correct bug when sentinel_value is not a timestamp
[Hassanin Ahmed](https://github.com/sas1ni69)
* [#531](https://github.com/rubysherpas/paranoia/pull/531) Added test case to reproduce bug introduce in v2.5.1
[Sherif Elkassaby](https://github.com/sherif-nedap)
* [#529](https://github.com/rubysherpas/paranoia/pull/529) Fix: Do not define a RSpec matcher when RSpec isn't present
[Sebastian Welther](https://github.com/swelther)

## 2.5.2

* [#526](https://github.com/rubysherpas/paranoia/pull/526) Do not include tests files in packaged gem

[Jason Fleetwood-Boldt](https://github.com/jasonfb)
* [#492](https://github.com/rubysherpas/paranoia/pull/492) Warn if acts_as_paranoid is called more than once on the same model

[Ignatius Reza](https://github.com/ignatiusreza)

## 2.5.1

* [#481](https://github.com/rubysherpas/paranoia/pull/481) Replaces hard coded `deleted_at` with `paranoia_column`.

[Hassanin Ahmed](https://github.com/sas1ni69)

## 2.5.0

* [#516](https://github.com/rubysherpas/paranoia/pull/516) Add support for ActiveRecord 7.0, drop support for EOL Ruby < 2.5 and Rails < 5.1
adding support for Rails 7

[Mathieu Jobin](https://github.com/mathieujobin)
* [#515](https://github.com/rubysherpas/paranoia/pull/515) Switch from Travis CI to GitHub Actions

[Shinichi Maeshima](https://github.com/willnet)

## 2.4.3

* [#503](https://github.com/rubysherpas/paranoia/pull/503) Bump activerecord dependency for Rails 6.1

[Jörg Schiller](https://github.com/joergschiller)

* [#483](https://github.com/rubysherpas/paranoia/pull/483) Update JRuby version to 9.2.8.0 + remove EOL Ruby 2.2

[Uwe Kubosch](https://github.com/donv)

* [#482](https://github.com/rubysherpas/paranoia/pull/482) Fix after_commit for Rails 6

[Ashwin Hegde](https://github.com/hashwin)

## 2.4.2

* [#470](https://github.com/rubysherpas/paranoia/pull/470) Add support for ActiveRecord 6.0

[Anton Kolodii](https://github.com/iggant), [Jared Norman](https://github.com/jarednorman)

## 2.4.1

* [#435](https://github.com/rubysherpas/paranoia/pull/435) Monkeypatch activerecord relations to work with rails 5.2.0
Expand Down
26 changes: 19 additions & 7 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,20 +1,32 @@
source 'https://rubygems.org'

gem 'sqlite3', platforms: [:ruby]
sqlite = ENV['SQLITE_VERSION']

if sqlite
gem 'sqlite3', sqlite, platforms: [:ruby]
else
gem 'sqlite3', platforms: [:ruby]
end

platforms :jruby do
gem 'activerecord-jdbcsqlite3-adapter'
end

platforms :rbx do
gem 'rubysl', '~> 2.0'
gem 'rubysl-test-unit'
gem 'rubinius-developer_tools'
if RUBY_ENGINE == 'rbx'
platforms :rbx do
gem 'rubinius-developer_tools'
gem 'rubysl', '~> 2.0'
gem 'rubysl-test-unit'
end
end

rails = ENV['RAILS'] || '~> 5.2.0'
rails = ENV['RAILS'] || '~> 6.0.4'

gem 'rails', rails
if rails == 'edge'
gem 'rails', github: 'rails/rails'
else
gem 'rails', rails
end

# Specify your gem's dependencies in paranoia.gemspec
gemspec
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[![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:**

`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 @@ -190,7 +193,7 @@ client.restore(:recursive => true)
If you want to restore a record and only those dependently destroyed associated records that were deleted within 2 minutes of the object upon which they depend:

``` ruby
Client.restore(id, :recursive => true. :recovery_window => 2.minutes)
Client.restore(id, :recursive => true, :recovery_window => 2.minutes)
# or
client.restore(:recursive => true, :recovery_window => 2.minutes)
```
Expand Down
51 changes: 39 additions & 12 deletions lib/paranoia.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require 'active_record' unless defined? ActiveRecord

if [ActiveRecord::VERSION::MAJOR, ActiveRecord::VERSION::MINOR] == [5, 2]
if [ActiveRecord::VERSION::MAJOR, ActiveRecord::VERSION::MINOR] == [5, 2] ||
ActiveRecord::VERSION::MAJOR > 5
require 'paranoia/active_record_5_2'
end

Expand Down Expand Up @@ -39,7 +40,7 @@ def only_deleted
# these will not match != sentinel value because "NULL != value" is
# NULL under the sql standard
# Scoping with the table_name is mandatory to avoid ambiguous errors when joining tables.
scoped_quoted_paranoia_column = "#{self.table_name}.#{connection.quote_column_name(paranoia_column)}"
scoped_quoted_paranoia_column = "#{connection.quote_table_name(self.table_name)}.#{connection.quote_column_name(paranoia_column)}"
with_deleted.where("#{scoped_quoted_paranoia_column} IS NULL OR #{scoped_quoted_paranoia_column} != ?", paranoia_sentinel_value)
end
alias_method :deleted, :only_deleted
Expand Down Expand Up @@ -97,8 +98,8 @@ def paranoia_update!(attributes)
end

def paranoia_destroy
transaction do
run_callbacks(:destroy) do
with_transaction_returning_status do
result = run_callbacks(:destroy) do
@_disable_counter_cache = deleted?
result = paranoia_delete
next result unless result && ActiveRecord::VERSION::STRING >= '4.2'
Expand All @@ -108,10 +109,13 @@ def paranoia_destroy
next unless send(association.reflection.name)
association.decrement_counters
end
@_trigger_destroy_callback = true
@_disable_counter_cache = false
result
end
end
raise ActiveRecord::Rollback, "Not destroyed" unless self.deleted?
result
end || false
end
alias_method :destroy, :paranoia_destroy

Expand All @@ -120,6 +124,10 @@ def paranoia_destroy!
raise(ActiveRecord::RecordNotDestroyed.new("Failed to destroy the record", self))
end

def trigger_transactional_callbacks?
super || @_trigger_destroy_callback && paranoia_destroyed?
end

def paranoia_delete
raise ActiveRecord::ReadOnlyRecord, "#{self.class} is marked as readonly" if readonly?
if persisted?
Expand Down Expand Up @@ -163,21 +171,21 @@ def restore!(opts = {})
def get_recovery_window_range(opts)
return opts[:recovery_window_range] if opts[:recovery_window_range]
return unless opts[:recovery_window]
(deleted_at - opts[:recovery_window]..deleted_at + opts[:recovery_window])
(deletion_time - opts[:recovery_window]..deletion_time + opts[:recovery_window])
end

def within_recovery_window?(recovery_window_range)
return true unless recovery_window_range
recovery_window_range.cover?(deleted_at)
recovery_window_range.cover?(deletion_time)
end

def paranoia_destroyed?
send(paranoia_column) != paranoia_sentinel_value
paranoia_column_value != paranoia_sentinel_value
end
alias :deleted? :paranoia_destroyed?

def really_destroy!
transaction do
with_transaction_returning_status do
run_callbacks(:real_destroy) do
@_disable_counter_cache = paranoia_destroyed?
dependent_reflections = self.class.reflections.select do |name, reflection|
Expand Down Expand Up @@ -264,13 +272,24 @@ def restore_associated_records(recovery_window_range = nil)
end
end

clear_association_cache if destroyed_associations.present?
if ActiveRecord.version.to_s > '7'
# Method deleted in https://github.com/rails/rails/commit/dd5886d00a2d5f31ccf504c391aad93deb014eb8
@association_cache.clear if persisted? && destroyed_associations.present?
else
clear_association_cache if destroyed_associations.present?
end
end
end

ActiveSupport.on_load(:active_record) do
class ActiveRecord::Base
def self.acts_as_paranoid(options={})
if included_modules.include?(Paranoia)
puts "[WARN] #{self.name} is calling acts_as_paranoid more than once!"

return
end

define_model_callbacks :restore, :real_destroy

alias_method :really_destroyed?, :destroyed?
Expand Down Expand Up @@ -319,9 +338,17 @@ def paranoia_column
self.class.paranoia_column
end

def paranoia_column_value
send(paranoia_column)
end

def paranoia_sentinel_value
self.class.paranoia_sentinel_value
end

def deletion_time
paranoia_column_value.acts_like?(:time) ? paranoia_column_value : deleted_at
end
end
end

Expand All @@ -345,12 +372,12 @@ def build_relation(klass, *args)
class UniquenessValidator < ActiveModel::EachValidator
prepend UniquenessParanoiaValidator
end

class AssociationNotSoftDestroyedValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
# if association is soft destroyed, add an error
if value.present? && value.paranoia_destroyed?
record.errors[attribute] << 'has been soft-deleted'
record.errors.add(attribute, 'has been soft-deleted')
end
end
end
Expand Down
37 changes: 20 additions & 17 deletions lib/paranoia/rspec.rb
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
require 'rspec/expectations'
if defined?(RSpec)
require 'rspec/expectations'

# Validate the subject's class did call "acts_as_paranoid"
RSpec::Matchers.define :act_as_paranoid do
match { |subject| subject.class.ancestors.include?(Paranoia) }
# Validate the subject's class did call "acts_as_paranoid"
RSpec::Matchers.define :act_as_paranoid do
match { |subject| subject.class.ancestors.include?(Paranoia) }

failure_message_proc = lambda do
"expected #{subject.class} to use `acts_as_paranoid`"
end
failure_message_proc = lambda do
"expected #{subject.class} to use `acts_as_paranoid`"
end

failure_message_when_negated_proc = lambda do
"expected #{subject.class} not to use `acts_as_paranoid`"
end
failure_message_when_negated_proc = lambda do
"expected #{subject.class} not to use `acts_as_paranoid`"
end

if respond_to?(:failure_message_when_negated)
failure_message(&failure_message_proc)
failure_message_when_negated(&failure_message_when_negated_proc)
else
# RSpec 2 compatibility:
failure_message_for_should(&failure_message_proc)
failure_message_for_should_not(&failure_message_when_negated_proc)
if respond_to?(:failure_message_when_negated)
failure_message(&failure_message_proc)
failure_message_when_negated(&failure_message_when_negated_proc)
else
# RSpec 2 compatibility:
failure_message_for_should(&failure_message_proc)
failure_message_for_should_not(&failure_message_when_negated_proc)
end
end

end
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.4.1'.freeze
VERSION = '2.5.3'.freeze
end
Loading

0 comments on commit 4878b30

Please sign in to comment.