acts_as_togglable 0.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 +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +100 -0
- data/lib/acts_as_togglable/model.rb +55 -0
- data/lib/acts_as_togglable/version.rb +3 -0
- data/lib/acts_as_togglable.rb +10 -0
- metadata +79 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 265a16f2f5d3dab3e3805e78ca640bc781176929977d5b9de352c64b4d6f88a3
|
|
4
|
+
data.tar.gz: 6e83b89e865a683548723f00a2bd0ac437c4e9f0640e79ca8b7f4de33fd3c68f
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 89f1568ad0cb1d4403c02f627a069ce2b0fb58690154d790970b5b387790028166b10d7947f9b6b0c940ee607aae9fea35ebe316126e8cd4c6f5738dd7cab186
|
|
7
|
+
data.tar.gz: 26234f7964b4dbc59bff3a640b468ef5fff8f11275db63a7c350396b0353ba85d4a70ca456d01f3b7e2ed8bc3c4b3b92c7e6630b94460846f1a300867cb7c71b
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jose Ferrer
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# acts_as_togglable
|
|
2
|
+
|
|
3
|
+
Named bang toggle methods for ActiveRecord boolean attributes.
|
|
4
|
+
|
|
5
|
+
Instead of `user.toggle!(:admin)` (which bypasses validations), get clean named methods like `user.admin!` that run validations and callbacks.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
Add to your Gemfile:
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
gem "acts_as_togglable"
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### Explicit mode
|
|
18
|
+
|
|
19
|
+
Specify which boolean attributes get bang methods:
|
|
20
|
+
|
|
21
|
+
```ruby
|
|
22
|
+
class User < ApplicationRecord
|
|
23
|
+
acts_as_togglable :admin, :active
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
user = User.create(admin: false, active: true)
|
|
27
|
+
user.admin! # => true (toggled and saved)
|
|
28
|
+
user.active! # => false (toggled and saved)
|
|
29
|
+
user.admin! # => false (toggled back)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Auto mode
|
|
33
|
+
|
|
34
|
+
Generate bang methods for all boolean columns:
|
|
35
|
+
|
|
36
|
+
```ruby
|
|
37
|
+
class Post < ApplicationRecord
|
|
38
|
+
acts_as_togglable
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
post = Post.create(published: false, featured: true)
|
|
42
|
+
post.published! # => true
|
|
43
|
+
post.featured! # => false
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## How it works
|
|
47
|
+
|
|
48
|
+
Each bang method:
|
|
49
|
+
|
|
50
|
+
- Toggles the boolean value
|
|
51
|
+
- Saves with `update!` (runs validations and callbacks)
|
|
52
|
+
- Returns the new boolean value
|
|
53
|
+
- Raises `ActiveRecord::RecordInvalid` if validations fail
|
|
54
|
+
|
|
55
|
+
## Why not just use `toggle!`?
|
|
56
|
+
|
|
57
|
+
Rails' built-in `toggle!` bypasses validations and callbacks. This matters when your app depends on them.
|
|
58
|
+
|
|
59
|
+
For example, a blog post that updates the sitemap when published:
|
|
60
|
+
|
|
61
|
+
```ruby
|
|
62
|
+
class Post < ApplicationRecord
|
|
63
|
+
acts_as_togglable :published
|
|
64
|
+
|
|
65
|
+
after_save :update_sitemap, if: :published?
|
|
66
|
+
|
|
67
|
+
private
|
|
68
|
+
|
|
69
|
+
def update_sitemap
|
|
70
|
+
SitemapGenerator.rebuild
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
```ruby
|
|
76
|
+
# With toggle! — callback is SKIPPED, sitemap not updated
|
|
77
|
+
post.toggle!(:published)
|
|
78
|
+
|
|
79
|
+
# With acts_as_togglable — callback fires, sitemap updated
|
|
80
|
+
post.published!
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Other cases where callbacks and validations matter:
|
|
84
|
+
|
|
85
|
+
- Sending a welcome email when a user is activated
|
|
86
|
+
- Logging an audit trail when permissions change
|
|
87
|
+
- Validating that only one post can be featured at a time
|
|
88
|
+
|
|
89
|
+
## Comparison with Rails toggle!
|
|
90
|
+
|
|
91
|
+
| | `acts_as_togglable` | Rails `toggle!` |
|
|
92
|
+
|---|---|---|
|
|
93
|
+
| Syntax | `user.admin!` | `user.toggle!(:admin)` |
|
|
94
|
+
| Validations | Runs | Bypassed |
|
|
95
|
+
| Callbacks | Runs | Bypassed |
|
|
96
|
+
| Return value | New boolean | `true` |
|
|
97
|
+
|
|
98
|
+
## License
|
|
99
|
+
|
|
100
|
+
MIT
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
require "active_support/concern"
|
|
2
|
+
|
|
3
|
+
module ActsAsTogglable
|
|
4
|
+
module Model
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
class_methods do
|
|
8
|
+
def acts_as_togglable(*attributes)
|
|
9
|
+
if attributes.any?
|
|
10
|
+
attributes.each do |attr|
|
|
11
|
+
define_method(:"#{attr}!") do
|
|
12
|
+
new_value = !public_send(attr)
|
|
13
|
+
update!(attr => new_value)
|
|
14
|
+
new_value
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
else
|
|
18
|
+
@_acts_as_togglable_auto = true
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def _acts_as_togglable_auto?
|
|
23
|
+
@_acts_as_togglable_auto == true
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def method_missing(method_name, *args, &block)
|
|
28
|
+
if self.class._acts_as_togglable_auto? && method_name.to_s.end_with?("!")
|
|
29
|
+
attr = method_name.to_s.chomp("!")
|
|
30
|
+
column = self.class.columns_hash[attr]
|
|
31
|
+
|
|
32
|
+
if column&.type == :boolean
|
|
33
|
+
self.class.define_method(method_name) do
|
|
34
|
+
new_value = !public_send(attr)
|
|
35
|
+
update!(attr => new_value)
|
|
36
|
+
new_value
|
|
37
|
+
end
|
|
38
|
+
return public_send(method_name)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
super
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def respond_to_missing?(method_name, include_private = false)
|
|
46
|
+
if self.class._acts_as_togglable_auto? && method_name.to_s.end_with?("!")
|
|
47
|
+
attr = method_name.to_s.chomp("!")
|
|
48
|
+
column = self.class.columns_hash[attr]
|
|
49
|
+
return true if column&.type == :boolean
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
super
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
require_relative "acts_as_togglable/version"
|
|
2
|
+
require_relative "acts_as_togglable/model"
|
|
3
|
+
|
|
4
|
+
if defined?(ActiveSupport.on_load)
|
|
5
|
+
ActiveSupport.on_load(:active_record) do
|
|
6
|
+
include ActsAsTogglable::Model
|
|
7
|
+
end
|
|
8
|
+
elsif defined?(ActiveRecord::Base)
|
|
9
|
+
ActiveRecord::Base.include(ActsAsTogglable::Model)
|
|
10
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: acts_as_togglable
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Jose Ferrer
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-02-03 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: activerecord
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '6.0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '6.0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: activesupport
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '6.0'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '6.0'
|
|
41
|
+
description: Adds methods like user.admin! that toggle boolean attributes with validations
|
|
42
|
+
and callbacks, unlike Rails toggle! which bypasses them.
|
|
43
|
+
email:
|
|
44
|
+
- estoy@moviendo.me
|
|
45
|
+
executables: []
|
|
46
|
+
extensions: []
|
|
47
|
+
extra_rdoc_files: []
|
|
48
|
+
files:
|
|
49
|
+
- LICENSE.txt
|
|
50
|
+
- README.md
|
|
51
|
+
- lib/acts_as_togglable.rb
|
|
52
|
+
- lib/acts_as_togglable/model.rb
|
|
53
|
+
- lib/acts_as_togglable/version.rb
|
|
54
|
+
homepage: https://github.com/moviendome/acts_as_togglable
|
|
55
|
+
licenses:
|
|
56
|
+
- MIT
|
|
57
|
+
metadata:
|
|
58
|
+
source_code_uri: https://github.com/moviendome/acts_as_togglable
|
|
59
|
+
changelog_uri: https://github.com/moviendome/acts_as_togglable/blob/main/CHANGELOG.md
|
|
60
|
+
post_install_message:
|
|
61
|
+
rdoc_options: []
|
|
62
|
+
require_paths:
|
|
63
|
+
- lib
|
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '3.0'
|
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
70
|
+
requirements:
|
|
71
|
+
- - ">="
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: '0'
|
|
74
|
+
requirements: []
|
|
75
|
+
rubygems_version: 3.5.22
|
|
76
|
+
signing_key:
|
|
77
|
+
specification_version: 4
|
|
78
|
+
summary: Named bang toggle methods for ActiveRecord booleans
|
|
79
|
+
test_files: []
|