Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rails 5 Support, Require ruby 2.0 #303

Merged
merged 12 commits into from
Feb 3, 2016
24 changes: 18 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,24 @@ sudo: false
language: ruby
rvm:
- 2.0.0
- 2.1.0
- 2.2.0
- 2.1.8
- 2.2.4
- 2.3.0
- jruby-19mode
- jruby-9.0.5.0

env:
- RAILS='~> 4.0.13'
- RAILS='~> 4.1.10'
- RAILS='~> 4.2.1'
matrix:
- RAILS='~> 4.0.13'
- RAILS='~> 4.1.10'
- RAILS='~> 4.2.1'
- RAILS='~> 5.0.0.beta1'

matrix:
exclude:
- env: RAILS='~> 5.0.0.beta1'
rvm: 2.0.0
- env: RAILS='~> 5.0.0.beta1'
rvm: 2.1.8
allow_failures:
- env: RAILS='~> 5.0.0.beta1'
rvm: jruby-9.0.5.0
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# paranoia Changelog

## 2.2.0 (unreleased)

* Ruby 2.0 or greater is required
* Rails 5.0.0.beta1.1 support [@pigeonworks](https://github.com/pigeonworks) [@halostatue](https://github.com/halostatue) and [@gagalago](https://github.com/gagalago)
* Previously `#really_destroyed?` may have been defined on non-paranoid models, it is now only available on paranoid models, use regular `#destroyed?` instead.

## 2.1.5 (2016-01-06)

* Ruby 2.3 support
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Paranoia

Paranoia is a re-implementation of [acts\_as\_paranoid](http://github.com/ActsAsParanoid/acts_as_paranoid) for Rails 3 and Rails 4, using much, much, much less code.
Paranoia is a re-implementation of [acts\_as\_paranoid](http://github.com/ActsAsParanoid/acts_as_paranoid) for Rails 3/4/5, using much, much, much less code.

When your app is using Paranoia, calling `destroy` on an ActiveRecord object doesn't actually destroy the database record, but just *hides* it. Paranoia does this by setting a `deleted_at` field to the current time when you `destroy` a record, and hides it by scoping all queries on your model to only include records which do not have a `deleted_at` field.

Expand All @@ -20,7 +20,7 @@ For Rails 3, please use version 1 of Paranoia:
gem "paranoia", "~> 1.0"
```

For Rails 4, please use version 2 of Paranoia:
For Rails 4 or 5, please use version 2 of Paranoia:

``` ruby
gem "paranoia", "~> 2.0"
Expand Down
27 changes: 17 additions & 10 deletions lib/paranoia.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def only_deleted
quoted_paranoia_column = connection.quote_column_name(paranoia_column)
with_deleted.where("#{quoted_paranoia_column} IS NULL OR #{quoted_paranoia_column} != ?", paranoia_sentinel_value)
end
alias :deleted :only_deleted
alias_method :deleted, :only_deleted

def restore(id_or_ids, opts = {})
ids = Array(id_or_ids).flatten
Expand Down Expand Up @@ -207,9 +207,9 @@ def restore_associated_records

class ActiveRecord::Base
def self.acts_as_paranoid(options={})
alias :really_destroyed? :destroyed?
alias :really_delete :delete
alias :destroy_without_paranoia :destroy
alias_method :really_destroyed?, :destroyed?
alias_method :really_delete, :delete
alias_method :destroy_without_paranoia, :destroy

include Paranoia
class_attribute :paranoia_column, :paranoia_sentinel_value
Expand Down Expand Up @@ -261,14 +261,21 @@ def paranoia_sentinel_value

module ActiveRecord
module Validations
class UniquenessValidator < ActiveModel::EachValidator
protected
def build_relation_with_paranoia(klass, table, attribute, value)
relation = build_relation_without_paranoia(klass, table, attribute, value)
module UniquenessParanoiaValidator
def build_relation(klass, table, attribute, value)
relation = super(klass, table, attribute, value)
return relation unless klass.respond_to?(:paranoia_column)
relation.and(klass.arel_table[klass.paranoia_column].eq(klass.paranoia_sentinel_value))
arel_paranoia_scope = klass.arel_table[klass.paranoia_column].eq(klass.paranoia_sentinel_value)
if ActiveRecord::VERSION::STRING >= "5.0"
relation.where(arel_paranoia_scope)
else
relation.and(arel_paranoia_scope)
end
end
alias_method_chain :build_relation, :paranoia
end

class UniquenessValidator < ActiveModel::EachValidator
prepend UniquenessParanoiaValidator
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.1.5"
VERSION = "2.2.0.alpha"
end
4 changes: 3 additions & 1 deletion paranoia.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ Gem::Specification.new do |s|
s.required_rubygems_version = ">= 1.3.6"
s.rubyforge_project = "paranoia"

s.add_dependency "activerecord", "~> 4.0"
s.required_ruby_version = '>= 2.0'

s.add_dependency 'activerecord', '>= 4.0', '< 5.1'

s.add_development_dependency "bundler", ">= 1.0.0"
s.add_development_dependency "rake"
Expand Down
28 changes: 20 additions & 8 deletions test/paranoia_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,15 @@ class WithDifferentConnection < ActiveRecord::Base

class ParanoiaTest < test_framework
def setup
ActiveRecord::Base.connection.tables.each do |table|
ActiveRecord::Base.connection.execute "DELETE FROM #{table}"
connection = ActiveRecord::Base.connection
cleaner = ->(source) {
ActiveRecord::Base.connection.execute "DELETE FROM #{source}"
}

if ActiveRecord::VERSION::MAJOR < 5
connection.tables.each(&cleaner)
else
connection.data_sources.each(&cleaner)
end
end

Expand Down Expand Up @@ -292,8 +299,7 @@ def test_destroy_behavior_for_has_one_with_build_and_validation_error
# Regression test for #24
def test_chaining_for_paranoid_models
scope = FeaturefulModel.where(:name => "foo").only_deleted
assert_equal "foo", scope.where_values_hash['name']
assert_equal 2, scope.where_values.count
assert_equal({'name' => "foo"}, scope.where_values_hash)
end

def test_only_destroyed_scope_for_paranoid_models
Expand Down Expand Up @@ -392,9 +398,9 @@ def test_destroy_on_unsaved_record
# Just to demonstrate the AR behaviour
model = NonParanoidModel.new
model.destroy!
assert model.really_destroyed?
assert model.destroyed?
model.destroy!
assert model.really_destroyed?
assert model.destroyed?

# Mirrors behaviour above
model = ParanoidModel.new
Expand Down Expand Up @@ -771,7 +777,7 @@ def test_updated_at_modification_on_restore
parent1 = ParentModel.create
pt1 = ParanoidModelWithTimestamp.create(:parent_model => parent1)
ParanoidModelWithTimestamp.record_timestamps = false
pt1.update_columns(created_at: 20.years.ago, updated_at: 10.years.ago, deleted_at: 10.years.ago)
pt1.update_columns(created_at: 20.years.ago, updated_at: 10.years.ago, deleted_at: 10.years.ago)
ParanoidModelWithTimestamp.record_timestamps = true
assert pt1.updated_at < 10.minutes.ago
refute pt1.deleted_at.nil?
Expand Down Expand Up @@ -957,7 +963,13 @@ class FailCallbackModel < ActiveRecord::Base
belongs_to :parent_model
acts_as_paranoid

before_destroy { |_| false }
before_destroy { |_|
if ActiveRecord::VERSION::MAJOR < 5
false
else
throw :abort
end
}
end

class FeaturefulModel < ActiveRecord::Base
Expand Down