concerns_on_rails 1.0.0 โ†’ 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0679c4f78651169ae85fbf3f27d0a301d6ca33c148eb3e01c766252145c5be4c'
4
- data.tar.gz: cec6963e3ba583e9072b03de751adbd1362dc100b041d5addf8cb37ebacd1d41
3
+ metadata.gz: 8810e1d51d69ba3de04b06ec9f372aca86611a0ac555b0d0652284680b35d37a
4
+ data.tar.gz: d6d8d480ffac223059af1942c0161ab7eff86b6af5320852838a2e5c0c9e3611
5
5
  SHA512:
6
- metadata.gz: c2ffaa1b86bd6c7952857c88e326009a85699bb77364e0b42e6cd8bfa11614917c3cf2fbae94af08bf2262210968878b65c37b22856bb8bac95345d81533fa57
7
- data.tar.gz: e387756b366d70efff292dd40b1a8cf34dfeb04321140c2e4e03833c754975afb1686df499fd6ddefc4e83e7c7347851e62c1bc2a8f7d1f9e51d0c7f3cae50ca
6
+ metadata.gz: fdc35dc31371b5bef4f0897494250778dcb794598136c21db6d33db5b165a0fc95151c2939ee610312249e3a6012738e0041673ce592846515eaa38b0a8dd453
7
+ data.tar.gz: b9704d4368ba22504f7b2bf6081832fd2e4a6014f74ea9a88abc73ab55dc0e4af07cc89d09cff6442d59357fa0907503eb19900e4165ef241e5183527e1b512f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  <!-- CHANGELOG.md -->
2
2
 
3
+ ## 1.1.0 (2025-04-17)
4
+
5
+ ### Added
6
+ - SoftDeletable: Add soft delete concern with configurable field, scopes, callbacks, and default_scope support
7
+
3
8
  ## 1.0.0 (2025-04-12)
4
9
 
5
10
  ### Added
data/README.md CHANGED
@@ -1,18 +1,19 @@
1
- # ConcernsOnRails
1
+ # ๐Ÿงฉ ConcernsOnRails
2
2
 
3
- **Note: Hoร ng Sa and Trฦฐแปng Sa belong to Viแป‡t Nam.** ๐Ÿ‡ป๐Ÿ‡ณ
3
+ **๐Ÿ‡ป๐Ÿ‡ณ Note: Hoร ng Sa and Trฦฐแปng Sa belong to Viแป‡t Nam.**
4
4
 
5
5
  A simple collection of reusable Rails concerns to keep your models clean and DRY.
6
6
 
7
- ## Features
7
+ ## โœจ Features
8
8
 
9
9
  - โœ… `Sluggable`: Generate friendly slugs from a specified field
10
- - โœ… `Sortable`: Sort records based on a field using `acts_as_list`, with flexible sorting field and direction
11
- - โœ… `Publishable`: Easily manage published/unpublished records using a simple `published_at` field
10
+ - ๐Ÿ”ข `Sortable`: Sort records based on a field using `acts_as_list`, with flexible sorting field and direction
11
+ - ๐Ÿ“ค `Publishable`: Easily manage published/unpublished records using a simple `published_at` field
12
+ - โŒ `SoftDeletable`: Soft delete records using a configurable timestamp field (e.g., `deleted_at`) with automatic scoping
12
13
 
13
14
  ---
14
15
 
15
- ## Installation
16
+ ## ๐Ÿ“ฆ Installation
16
17
 
17
18
  Add this line to your application's Gemfile:
18
19
 
@@ -28,9 +29,9 @@ bundle install
28
29
 
29
30
  ---
30
31
 
31
- ## Usage
32
+ ## ๐Ÿš€ Usage
32
33
 
33
- ### 1. Sluggable
34
+ ### 1. ๐Ÿ“ Sluggable
34
35
 
35
36
  Add slugs based on a specified attribute.
36
37
 
@@ -49,7 +50,7 @@ If the slug source is changed, the slug will auto-update.
49
50
 
50
51
  ---
51
52
 
52
- ### 2. Sortable
53
+ ### 2. ๐Ÿ”ข Sortable
53
54
 
54
55
  Use for models that need ordering.
55
56
 
@@ -76,16 +77,16 @@ end
76
77
  ```
77
78
 
78
79
  Additional features:
79
- - Automatically sets `acts_as_list` on the configured column
80
- - Adds default sorting scope to your model
81
- - Supports custom direction: `:asc` or `:desc`
82
- - Validates that the sortable field exists in the table schema
83
- - Compatible with scopes and ActiveRecord queries
84
- - Can be reconfigured dynamically within the model using `sortable_by`
80
+ - ๐Ÿ“Œ Automatically sets `acts_as_list` on the configured column
81
+ - ๐Ÿ“‹ Adds default sorting scope to your model
82
+ - โ†•๏ธ Supports custom direction: `:asc` or `:desc`
83
+ - ๐Ÿ” Validates that the sortable field exists in the table schema
84
+ - ๐Ÿง  Compatible with scopes and ActiveRecord queries
85
+ - ๐Ÿ”„ Can be reconfigured dynamically within the model using `sortable_by`
85
86
 
86
87
  ---
87
88
 
88
- ### 3. Publishable
89
+ ### 3. ๐Ÿ“ค Publishable
89
90
 
90
91
  Manage published/unpublished records using a `published_at` field.
91
92
 
@@ -108,17 +109,51 @@ article.published? # => false
108
109
  ```
109
110
 
110
111
  Additional features:
111
- - `published?` returns true if `published_at` is present and in the past
112
- - `publish!` sets `published_at` to current time
113
- - `unpublish!` sets `published_at` to `nil`
114
- - Add scopes: `.published`, `.unpublished`, and a default scope (optional)
115
- - Ideal for blog posts, articles, or any content that toggles visibility
116
- - Lightweight and non-invasive
117
- - Easy to test and override in custom implementations
112
+ - โœ… `published?` returns true if `published_at` is present and in the past
113
+ - ๐Ÿ•’ `publish!` sets `published_at` to current time
114
+ - ๐Ÿšซ `unpublish!` sets `published_at` to `nil`
115
+ - ๐Ÿ”Ž Add scopes: `.published`, `.unpublished`, and a default scope (optional)
116
+ - ๐Ÿ“ฐ Ideal for blog posts, articles, or any content that toggles visibility
117
+ - ๐Ÿงฉ Lightweight and non-invasive
118
+ - ๐Ÿงช Easy to test and override in custom implementations
118
119
 
119
120
  ---
120
121
 
121
- ## Development
122
+ ### 4. โŒ SoftDeletable
123
+
124
+ Soft delete records using a timestamp field (default: `deleted_at`).
125
+
126
+ ```ruby
127
+ class User < ApplicationRecord
128
+ include ConcernsOnRails::SoftDeletable
129
+
130
+ soft_deletable_by :deleted_at
131
+ end
132
+
133
+ user = User.create!(name: "Alice")
134
+ user.soft_delete!
135
+ user.deleted? # => true
136
+
137
+ User.without_deleted # => returns only active users
138
+ User.soft_deleted # => returns soft-deleted users
139
+ User.all # => returns only non-deleted by default (default_scope applied)
140
+
141
+ user.restore!
142
+ user.deleted? # => false
143
+ ```
144
+
145
+ Additional features:
146
+ - Default field is `deleted_at`, can be configured
147
+ - Automatically applies `default_scope` to hide soft-deleted records
148
+ - Scopes: `without_deleted`, `soft_deleted`, `active`
149
+ - Methods: `soft_delete!`, `restore!`, `deleted?`, `really_delete!`
150
+ - Callbacks: `before_soft_delete`, `after_soft_delete`, `before_restore`, `after_restore`
151
+ - Touch support when soft deleting or restoring (can be turned off)
152
+ - Aliases for `deleted?`: `soft_deleted?`, `is_soft_deleted?`
153
+
154
+ ---
155
+
156
+ ## ๐Ÿ› ๏ธ Development
122
157
 
123
158
  To build the gem:
124
159
 
@@ -134,13 +169,13 @@ gem install ./concerns_on_rails-1.0.0.gem
134
169
 
135
170
  ---
136
171
 
137
- ## Contributing
172
+ ## ๐Ÿค Contributing
138
173
 
139
174
  Bug reports and pull requests are welcome!
140
175
 
141
176
  ---
142
177
 
143
- ## License
178
+ ## ๐Ÿ“„ License
144
179
 
145
180
  This project is licensed under the MIT License.
146
181
 
@@ -150,11 +185,11 @@ This project is licensed under the MIT License.
150
185
 
151
186
  ---
152
187
 
153
- ### ๐Ÿ“ฆ Source Code
188
+ ### ๐Ÿ”— Source Code
154
189
 
155
190
  The source code is available on GitHub:
156
191
 
157
- ๐Ÿ”— [https://github.com/VSN2015/concerns_on_rails](https://github.com/VSN2015/concerns_on_rails)
192
+ [๐Ÿ‘‰ https://github.com/VSN2015/concerns_on_rails](https://github.com/VSN2015/concerns_on_rails)
158
193
 
159
194
  Feel free to star โญ๏ธ, fork ๐Ÿด, or contribute with issues and PRs.
160
195
 
@@ -7,7 +7,7 @@ module ConcernsOnRails
7
7
  # instance methods
8
8
  included do
9
9
  # declare class attributes and set default values
10
- class_attribute :publishable_field
10
+ class_attribute :publishable_field, instance_accessor: false
11
11
  self.publishable_field ||= :published_at
12
12
  end
13
13
 
@@ -8,7 +8,7 @@ module ConcernsOnRails
8
8
  # instance methods
9
9
  included do
10
10
  # declare class attributes and set default values
11
- class_attribute :sluggable_field
11
+ class_attribute :sluggable_field, instance_accessor: false
12
12
  self.sluggable_field ||= :name
13
13
 
14
14
  extend FriendlyId
@@ -0,0 +1,103 @@
1
+ require "active_support/concern"
2
+
3
+ module ConcernsOnRails
4
+ module SoftDeletable
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ # declare class attributes and set default values
9
+ class_attribute :soft_delete_field, instance_accessor: false, default: :deleted_at
10
+ class_attribute :soft_delete_touch, instance_accessor: false, default: true
11
+
12
+ # scopes
13
+ scope :active, -> { unscope(where: soft_delete_field).where(soft_delete_field => nil) }
14
+ scope :without_deleted, -> { unscope(where: soft_delete_field).where(soft_delete_field => nil) }
15
+ scope :soft_deleted, -> { unscope(where: soft_delete_field).where.not(soft_delete_field => nil) }
16
+ # Optionally, uncomment to hide deleted by default:
17
+ default_scope { without_deleted }
18
+
19
+ # define callbacks
20
+ define_model_callbacks :soft_delete
21
+ define_model_callbacks :restore
22
+ end
23
+
24
+ class_methods do
25
+ # Define soft delete field and options
26
+ # Example:
27
+ # soft_deletable_by :deleted_at, touch: false
28
+ def soft_deletable_by(field = nil, touch: true)
29
+ self.soft_delete_field = field || :deleted_at
30
+ self.soft_delete_touch = touch
31
+
32
+ unless column_names.include?(soft_delete_field.to_s)
33
+ raise ArgumentError, "ConcernsOnRails::SoftDeletable: soft_delete_field '#{soft_delete_field}' does not exist in the database"
34
+ end
35
+ end
36
+ end
37
+
38
+ # Soft delete hooks
39
+ def before_soft_delete; end
40
+ def after_soft_delete; end
41
+ def before_restore; end
42
+ def after_restore; end
43
+
44
+ # add soft delete methods
45
+ def soft_delete!
46
+ return true if deleted?
47
+ run_callbacks(:soft_delete) do
48
+ before_soft_delete
49
+ if self.class.soft_delete_touch
50
+ update(self.class.soft_delete_field => Time.zone.now).tap do |result|
51
+ touch if respond_to?(:touch)
52
+ after_soft_delete if result
53
+ end
54
+ else
55
+ update_column(self.class.soft_delete_field, Time.zone.now).tap do |result|
56
+ after_soft_delete if result
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ # really delete the record
63
+ def really_delete!
64
+ destroy
65
+ end
66
+
67
+ def restore!
68
+ run_callbacks(:restore) do
69
+ before_restore
70
+ if self.class.soft_delete_touch
71
+ update(self.class.soft_delete_field => nil).tap do |result|
72
+ touch if respond_to?(:touch)
73
+ after_restore if result
74
+ end
75
+ else
76
+ update_column(self.class.soft_delete_field, nil).tap do |result|
77
+ after_restore if result
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ def deleted?
84
+ self[self.class.soft_delete_field].present?
85
+ end
86
+
87
+ # alias methods
88
+ # define here to avoid issue: undefined method `deleted?' for module `ConcernsOnRails::SoftDeletable'
89
+ alias_method :is_soft_deleted?, :deleted?
90
+ alias_method :soft_deleted?, :deleted?
91
+
92
+ # Is really deleted?
93
+ def is_really_deleted?
94
+ !self.class.exists?(id)
95
+ end
96
+ end
97
+ end
98
+
99
+ # Usage Example:
100
+ # class MyModel < ApplicationRecord
101
+ # include ConcernsOnRails::SoftDeletable
102
+ # soft_deletable_by :deleted_at
103
+ # end
@@ -14,8 +14,8 @@ module ConcernsOnRails
14
14
  # end
15
15
  included do
16
16
  # declare class attributes
17
- class_attribute :sortable_field
18
- class_attribute :sortable_direction
17
+ class_attribute :sortable_field, instance_accessor: false
18
+ class_attribute :sortable_direction, instance_accessor: false
19
19
 
20
20
  # set default values
21
21
  self.sortable_field ||= :position
@@ -1,3 +1,3 @@
1
1
  module ConcernsOnRails
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -3,6 +3,7 @@ require "concerns_on_rails/version"
3
3
  require "concerns_on_rails/sortable"
4
4
  require "concerns_on_rails/publishable"
5
5
  require "concerns_on_rails/sluggable"
6
+ require "concerns_on_rails/soft_deletable"
6
7
 
7
8
  module ConcernsOnRails
8
9
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: concerns_on_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ethan Nguyen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-04-12 00:00:00.000000000 Z
11
+ date: 2025-04-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -66,6 +66,7 @@ files:
66
66
  - lib/concerns_on_rails.rb
67
67
  - lib/concerns_on_rails/publishable.rb
68
68
  - lib/concerns_on_rails/sluggable.rb
69
+ - lib/concerns_on_rails/soft_deletable.rb
69
70
  - lib/concerns_on_rails/sortable.rb
70
71
  - lib/concerns_on_rails/version.rb
71
72
  homepage: https://github.com/VSN2015/concerns_on_rails