make_taggable 1.1.0 → 1.1.1

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: 9313e4b6fc5d1b81f44b56665f2dbf6c6a8c8a8213f492b00e17e1e20c0a27bb
4
- data.tar.gz: ef32dbb42368817bea0791803f1013f1481d58ca50992551131483b7fac416ab
3
+ metadata.gz: 7d3a7c89a48d79f6d985b8290d88007368ecdf983789a7e4881662724a1060a9
4
+ data.tar.gz: dda60e219b50e10b8948b6b9b260e703d8815f43bd200b1c434875144ae68071
5
5
  SHA512:
6
- metadata.gz: 750c882a7d5836848cfd7d536896403cb619868121a817d9aa89ac2aed7e36d6f3d9cf70be5be04e1dd428e35484957b1f49ba17a2e7ef50f2a67adc271d7510
7
- data.tar.gz: d14dba688a46a5e48507a082d7b65071aa8e0197df657156c3859652fcabd8eca5e0c5256033f7a9c4665d197c87177f0d9107c010e811d671fc1de2011b4d1f
6
+ metadata.gz: 7aa7e8b6c7190cbc8fbdcaf54fd5f49bf8f877c3161c7466e7df98eefd8f14eaa208391b47fa5a328db563d489d5e9a6f82b3bfd4b0ce770cdedbf3423f958bc
7
+ data.tar.gz: 0e868727368e57e72fe627cbbc4b7a4dc2077e459d6ac9131732788fec26a88037bd7ed12cb86a35f3b8308b3df7fa238319c24628f39e698c073e7d0dd8fa68
data/CHANGELOG.md CHANGED
@@ -5,6 +5,21 @@ All notable changes to this project are documented here.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
6
6
  adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.1.1] - 2026-08-22
9
+
10
+ ### Fixed
11
+
12
+ - Documentation examples used `params.expect` and `ActiveRecord::Migration[8.0]`, neither of which
13
+ exists on Active Record 7.2 -- the version the gem promises to support. Both are corrected, and
14
+ `spec/docs_spec.rb` now fails the build if either creeps back.
15
+
16
+ ### Internal
17
+
18
+ - Added documentation checks to the suite: every Ruby block in the README and `docs/` must parse,
19
+ example migrations must declare a version the floor accepts, version-sensitive calls must be
20
+ shown alongside an alternative, and relative links must resolve. They run on every Rails version
21
+ in the matrix.
22
+
8
23
  ## [1.1.0] - 2026-08-22
9
24
 
10
25
  ### Added
data/CONTRIBUTING.md CHANGED
@@ -64,6 +64,12 @@ Prose documentation lives in [docs/](docs). API documentation is YARD comments i
64
64
  the style already there: a `##` opening line, a description, a blank line, then tags with real Ruby
65
65
  types.
66
66
 
67
+ `spec/docs_spec.rb` holds the prose to the versions the gemspec promises. It checks that every Ruby
68
+ block parses, that no example declares a migration version newer than the supported floor, that
69
+ calls the floor does not have are shown alongside an alternative, and that every relative link
70
+ resolves. It runs with the rest of the suite, so it runs on every Rails version in the matrix --
71
+ including the oldest, which is where documentation written on the newest tends to break.
72
+
67
73
  Build it locally with `bundle exec yard doc`.
68
74
 
69
75
  ## Releasing
data/README.md CHANGED
@@ -1,7 +1,8 @@
1
1
  # MakeTaggable
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/make_taggable.svg)](https://badge.fury.io/rb/make_taggable)
4
- ![CI](https://github.com/MatthewKennedy/make_taggable/workflows/CI/badge.svg)
3
+ [![Gem Version](https://img.shields.io/gem/v/make_taggable)](https://rubygems.org/gems/make_taggable)
4
+ [![Downloads](https://img.shields.io/gem/dt/make_taggable)](https://rubygems.org/gems/make_taggable)
5
+ [![CI](https://github.com/MatthewKennedy/make_taggable/actions/workflows/ci.yml/badge.svg)](https://github.com/MatthewKennedy/make_taggable/actions/workflows/ci.yml)
5
6
  [![Standard Rb](https://github.com/MatthewKennedy/make_taggable/actions/workflows/standard-ci.yml/badge.svg)](https://github.com/MatthewKennedy/make_taggable/actions/workflows/standard-ci.yml)
6
7
 
7
8
  Tagging for Active Record models, across any number of named contexts.
@@ -12,7 +13,7 @@ order they were added in, and be cached on the record for display.
12
13
 
13
14
  ## Requirements
14
15
 
15
- | | |
16
+ | Component | Supported |
16
17
  |---|---|
17
18
  | Ruby | 3.2 or newer |
18
19
  | Active Record | 7.2 or newer |
@@ -35,44 +36,73 @@ rails db:migrate
35
36
 
36
37
  ```ruby
37
38
  class Book < ApplicationRecord
38
- make_taggable # the :tags context
39
- make_taggable :genres # and one of your own
39
+ make_taggable # the :tags context, for free-form tags
40
+ make_taggable :genres # a context of your own, for a curated set
40
41
  end
41
42
  ```
42
43
 
44
+ Each context is a separate set of tags, with its own list:
45
+
43
46
  ```ruby
44
- book = Book.create!(title: "Dune", tag_list: "sci-fi, classic")
47
+ book = Book.create!(title: "Dune", genre_list: "sci-fi, classic")
48
+
49
+ book.genre_list # => ["sci-fi", "classic"]
50
+ ```
45
51
 
46
- book.tag_list # => ["sci-fi", "classic"]
47
- book.tag_list.add("desert")
48
- book.tag_list.remove("classic")
52
+ Add and remove individual tags. Nothing is written until you save:
53
+
54
+ ```ruby
55
+ book.genre_list.add("space opera")
56
+ book.genre_list.remove("classic")
49
57
  book.save
50
58
 
51
- book.genre_list = "science fiction"
59
+ book.genre_list # => ["sci-fi", "space opera"]
60
+ book.genres # => [#<MakeTaggable::Tag name: "sci-fi">, #<MakeTaggable::Tag name: "space opera">]
61
+ ```
62
+
63
+ Assigning replaces the whole list, and the two contexts never touch each other:
64
+
65
+ ```ruby
66
+ book.tag_list = "desert, chosen-one, re-read"
52
67
  book.save
68
+
69
+ book.tag_list # => ["desert", "chosen-one", "re-read"]
70
+ book.genre_list # => ["sci-fi", "space opera"]
53
71
  ```
54
72
 
55
73
  Find them again:
56
74
 
57
75
  ```ruby
58
76
  Book.tagged_with("sci-fi") # carries this tag
59
- Book.tagged_with(["sci-fi", "desert"]) # carries both
77
+ Book.tagged_with(["sci-fi", "space opera"]) # carries both
60
78
  Book.tagged_with(["sci-fi", "fantasy"], any: true) # carries either
61
- Book.tagged_with(["sci-fi"], exclude: true) # carries neither
79
+ Book.tagged_with(["fantasy"], exclude: true) # carries neither
80
+ ```
81
+
82
+ Scope a query to one context, and tags in the others stop counting:
83
+
84
+ ```ruby
85
+ Book.tagged_with("sci-fi", on: :genres) # => [#<Book title: "Dune">]
86
+ Book.tagged_with("sci-fi", on: :tags) # => []
87
+ ```
62
88
 
63
- Book.tag_counts_on(:genres) # tags with usage counts
89
+ Counts, for tag clouds and "most used" lists:
90
+
91
+ ```ruby
92
+ Book.tag_counts_on(:genres) # tags carrying a `count`
64
93
  Book.top_genres(10)
65
94
  ```
66
95
 
67
96
  Tags are ordinary attributes as far as your controller is concerned:
68
97
 
69
98
  ```ruby
70
- params.expect(book: [:title, :tag_list])
99
+ params.expect(book: [:title, :tag_list]) # Rails 8
100
+ params.require(:book).permit(:title, :tag_list) # Rails 7.2
71
101
  ```
72
102
 
73
103
  ## Documentation
74
104
 
75
- | | |
105
+ | Guide | Covers |
76
106
  |---|---|
77
107
  | [Getting started](docs/getting-started.md) | Install, first tagged model, reading and writing |
78
108
  | [Tag contexts](docs/contexts.md) | Multiple contexts, ordered tags, contexts created at runtime |
data/docs/caching.md CHANGED
@@ -10,7 +10,7 @@ There is no setting. Add a column named `cached_<singular context>_list` and cac
10
10
  itself on for that context:
11
11
 
12
12
  ```ruby
13
- class AddCachedTagListToBooks < ActiveRecord::Migration[8.0]
13
+ class AddCachedTagListToBooks < ActiveRecord::Migration[7.2]
14
14
  def change
15
15
  add_column :books, :cached_tag_list, :string
16
16
  add_column :books, :cached_genre_list, :string
data/docs/contexts.md CHANGED
@@ -46,10 +46,15 @@ Calling `make_taggable` again adds contexts rather than replacing them, which is
46
46
  subclass extend its parent:
47
47
 
48
48
  ```ruby
49
+ class Book < ApplicationRecord
50
+ make_taggable
51
+ end
52
+
49
53
  class Manual < Book
50
54
  make_taggable :audiences
51
55
  end
52
56
 
57
+ Book.tag_types # => [:tags]
53
58
  Manual.tag_types # => [:tags, :audiences]
54
59
  ```
55
60
 
@@ -134,7 +139,7 @@ tags, `Market.count` returns every tag in the table, and reloading a record give
134
139
  `MakeTaggable::Tag` back. Add the column to get real separation:
135
140
 
136
141
  ```ruby
137
- class AddTypeToTags < ActiveRecord::Migration[8.0]
142
+ class AddTypeToTags < ActiveRecord::Migration[7.2]
138
143
  def change
139
144
  add_column MakeTaggable.tags_table, :type, :string
140
145
  add_index MakeTaggable.tags_table, :type
@@ -83,15 +83,19 @@ class BooksController < ApplicationController
83
83
  private
84
84
 
85
85
  def book_params
86
- params.expect(book: [:title, :tag_list])
86
+ params.expect(book: [:title, :tag_list]) # Rails 8
87
+ # params.require(:book).permit(:title, :tag_list) # Rails 7.2
87
88
  end
88
89
  end
89
90
  ```
90
91
 
92
+ `params.expect` arrived in Rails 8. On Rails 7.2 use `require` and `permit`, as commented above.
93
+
91
94
  To accept an array of tags from a multi-select, permit it as one:
92
95
 
93
96
  ```ruby
94
- params.expect(book: [:title, {tag_list: []}])
97
+ params.expect(book: [:title, {tag_list: []}]) # Rails 8
98
+ params.require(:book).permit(:title, tag_list: []) # Rails 7.2
95
99
  ```
96
100
 
97
101
  ## Find tagged records
data/docs/querying.md CHANGED
@@ -6,18 +6,18 @@
6
6
  pagination.
7
7
 
8
8
  ```ruby
9
- User.tagged_with("awesome").by_join_date.limit(20)
9
+ Book.tagged_with("sci-fi").order(published_at: :desc).limit(20)
10
10
  ```
11
11
 
12
12
  By default every tag given must be present:
13
13
 
14
14
  ```ruby
15
- User.tagged_with(["awesome", "cool"]) # carries awesome AND cool
16
- User.tagged_with(["awesome", "cool"], any: true) # carries awesome OR cool
17
- User.tagged_with(["awesome", "cool"], exclude: true) # carries NEITHER
15
+ Book.tagged_with(["sci-fi", "classic"]) # carries sci-fi AND classic
16
+ Book.tagged_with(["sci-fi", "classic"], any: true) # carries sci-fi OR classic
17
+ Book.tagged_with(["sci-fi", "classic"], exclude: true) # carries NEITHER
18
18
  ```
19
19
 
20
- Passing nothing matches nothing. `User.tagged_with([])` and `User.tagged_with("")` both return an
20
+ Passing nothing matches nothing. `Book.tagged_with([])` and `Book.tagged_with("")` both return an
21
21
  empty relation rather than every record — worth knowing when the tags come from user input.
22
22
 
23
23
  ### Options
@@ -27,7 +27,7 @@ empty relation rather than every record — worth knowing when the tags come fro
27
27
  | `:any` | Match records carrying at least one of the tags |
28
28
  | `:exclude` | Match records carrying none of the tags |
29
29
  | `:match_all` | Match records carrying only these tags and no others |
30
- | `:wild` | Match tags *containing* the given text, i.e. `%awesome%` |
30
+ | `:wild` | Match tags *containing* the given text, i.e. `%sci%` |
31
31
  | `:on` | Restrict to one context |
32
32
  | `:owned_by` | Restrict to tags applied by one tagger |
33
33
  | `:order_by_matching_tag_count` | With `:any`, order by how many tags matched, most first |
@@ -37,15 +37,15 @@ empty relation rather than every record — worth knowing when the tags come fro
37
37
  `:wild` combines with `:any` or `:exclude`:
38
38
 
39
39
  ```ruby
40
- User.tagged_with(["awe", "co"], any: true, wild: true)
40
+ Book.tagged_with(["sci", "clas"], any: true, wild: true)
41
41
  ```
42
42
 
43
43
  Contexts are matched one call at a time, so chain to combine them:
44
44
 
45
45
  ```ruby
46
- User
47
- .tagged_with(["awesome", "cool"], on: :tags, any: true)
48
- .tagged_with(["smart", "shy"], on: :skills, any: true)
46
+ Book
47
+ .tagged_with(["sci-fi", "fantasy"], on: :genres, any: true)
48
+ .tagged_with(["desert", "space"], on: :tags, any: true)
49
49
  ```
50
50
 
51
51
  ### Case sensitivity
@@ -105,6 +105,9 @@ noticeably cheaper on a large table.
105
105
 
106
106
  ## Related records
107
107
 
108
+ These examples switch to a `User` model tagged on `:skills` — sharing tags is easiest to picture
109
+ with people.
110
+
108
111
  Records sharing tags with this one, ordered by how many tags matched:
109
112
 
110
113
  ```ruby
@@ -6,5 +6,5 @@ module MakeTaggable
6
6
  #
7
7
  # @return [String]
8
8
  #
9
- VERSION = "1.1.0"
9
+ VERSION = "1.1.1"
10
10
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: make_taggable
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Kennedy