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

Mongoid paranoia support #273

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .github/workflows/rubocop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
name: Rubocop

on: [push, pull_request]

jobs:
build:
runs-on: ubuntu-latest
env:
CI: true
TESTOPTS: '-v'
steps:
- uses: actions/checkout@v3
- name: Set up Ruby 3.2
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.2
bundler-cache: true
- name: bundle install
run: bundle install --jobs 4 --retry 3
johnnyshields marked this conversation as resolved.
Show resolved Hide resolved
- name: Run Rubocop
run: bundle exec rubocop --parallel
14 changes: 5 additions & 9 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,16 @@ jobs:
experimental: [false]
include:
- ruby: 3.2
mongoid: HEAD
mongoid: head
experimental: true
- ruby: head
mongoid: 7
experimental: true
- ruby: head
mongoid: HEAD
mongoid: head
experimental: true
- ruby: jruby
mongoid: 7
experimental: true
- ruby: jruby
mongoid: 8
Expand Down Expand Up @@ -58,13 +61,6 @@ jobs:
env:
MONGOID_VERSION: ${{ matrix.mongoid }}

- name: rubocop
timeout-minutes: 5
run: bundle exec rubocop
continue-on-error: ${{ matrix.experimental }}
env:
MONGOID_VERSION: ${{ matrix.mongoid }}

- name: test
timeout-minutes: 10
run: bundle exec rake spec
Expand Down
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
## 7.0.1 (Next)
## 7.1.1 (Next)

* Your contribution here.

## 7.1.0 (2023/09/18)

* [#273](https://github.com/mongoid/mongoid-slug/pull/273): Add optional Mongoid::Paranoia support - [@johnnyshields](https://github.com/johnnyshields)

## 7.0.0 (2023/09/18)

* [#270](https://github.com/mongoid/mongoid-slug/pull/270): Drop support for Mongoid prior to version 7.0 - [@johnnyshields](https://github.com/johnnyshields)
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 @@ source 'https://rubygems.org'
gemspec name: 'mongoid-slug'

case (version = ENV['MONGOID_VERSION'] || '8')
when 'HEAD'
when /\Ahead\z/i
gem 'mongoid', github: 'mongodb/mongoid'
when /\A\d+\z/
gem 'mongoid', "~> #{version}.0"
Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,19 @@ unique = Mongoid::Slug::UniqueSlug.new(Book.new).find_unique(title)
# return some representation of unique
```

### Compatibility with Mongoid::Paranoia

The [Mongoid::Paranoia](https://github.com/simi/mongoid_paranoia) gem provides soft-delete
functionality. If you are using this gem, please enable the global `use_paranoia` option.
This will automatically ensure that slugs will be cleared when soft-deleting a document,
and re-set when restoring a document.

```ruby
Mongoid::Slug.configure do |c|
c.use_paranoia = true
end
```

Contributing
------------

Expand Down
30 changes: 28 additions & 2 deletions lib/mongoid/slug.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ module Slug
end

class << self
attr_accessor :default_slug
attr_accessor :default_slug,
:use_paranoia

def configure(&block)
instance_eval(&block)
Expand Down Expand Up @@ -103,6 +104,17 @@ def slug(*fields, &block)
else
set_callback :save, :before, :build_slug, if: :slug_should_be_rebuilt?
end

# If paranoid document:
# - unset slugs on soft-destroy
# - recreate the slug on restore
# - force reset the slug when saving a destroyed paranoid document, to ensure it stays unset in the database
if __slug_paranoid_doc? # rubocop:disable Style/GuardClause
set_callback :destroy, :after, :unset_slug!
set_callback :restore, :before, :set_slug!
set_callback :save, :before, :reset_slug!, if: :slug_paranoid_deleted?
set_callback :save, :after, :clear_slug!, if: :slug_paranoid_deleted?
end
end

def default_slug_url_builder
Expand Down Expand Up @@ -147,6 +159,16 @@ def queryable
current_scope || Criteria.new(self) # Use Mongoid::Slug::Criteria for slugged documents.
end

# Returns whether to use paranoid functionality for this document.
#
# @return [ true | false ] Whether to use paranoid functionality
# for this document.
#
# @api private
def __slug_paranoid_doc?
!!(Mongoid::Slug.use_paranoia && defined?(::Mongoid::Paranoia) && self < ::Mongoid::Paranoia)
end

private

if Threaded.method(:current_scope).arity == -1
Expand Down Expand Up @@ -237,7 +259,11 @@ def find_unique_slug

# @return [Boolean] Whether the slug requires to be rebuilt
def slug_should_be_rebuilt?
new_record? || _slugs_changed? || slugged_attributes_changed?
(new_record? || _slugs_changed? || slugged_attributes_changed?) && !slug_paranoid_deleted?
end

def slug_paranoid_deleted?
!!(self.class.__slug_paranoid_doc? && !deleted_at.nil?)
end

def slugged_attributes_changed?
Expand Down