gutentag 2.6.2 → 3.0.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: 98f15b646e502b6b79038023b1e36b4b1d148cb99744134254165ad0997733ff
4
- data.tar.gz: d5f73cf67e7c0992a01730506a63567ecb62bf27bd934036c04c2fa80383eff6
3
+ metadata.gz: 5afcb64119c9fff07b6c4cb8786da632f3ad66d230ea049b45b7780440b9692a
4
+ data.tar.gz: ed0b54305d58152e70ec3de7b5cc324c5a443a1b0f73ade5e136cedb785b77f0
5
5
  SHA512:
6
- metadata.gz: 3fcff8de1bf31f8c7c31183c868445e68e4ea22b836c55512b8b423efeaee1cc72f2b6b40cf5e7d3749371a87a3e8627318aa831ceb8b6a2aaeb6b30f30237fb
7
- data.tar.gz: 538d5d06ce5ddad20ea227cc6ea090d6b2cead6afe97259fa7d01f6c7f80863c86ca13a66e9c8ab39f56d22ea6f34106e3cc1f32a5ce2a92d15021d3a055a0ef
6
+ metadata.gz: 4457511634f9ffee17502b8deab34ff6a306750dc0886864cd913c68f0e60c52873a4716ef6941ee23955477ca5b72847b3d644d8dfca6e0ccc16a8d7e27bf6f
7
+ data.tar.gz: 355801ea0a573f02a509ece9c9175786672c79d457e7ed5935ca6b73552a9fcc6cad065c9c65bb42b29adce1958957f73ef5dc1ef7244ac65dedfdcae7f4c772
@@ -1,34 +1,20 @@
1
1
  name: CI
2
2
 
3
- on: [push, pull_request]
3
+ on: [push]
4
4
 
5
5
  jobs:
6
6
  test:
7
- runs-on: ubuntu-18.04
7
+ runs-on: ubuntu-22.04
8
8
 
9
9
  strategy:
10
10
  fail-fast: false
11
11
  matrix:
12
- ruby: [ '2.4', '2.5', '2.6', '2.7', '3.0', '3.1' ]
13
- bundler: [ '1.17.3', '2.1.4' ]
12
+ ruby: [ '3.0', '3.1', '3.2', '3.3', '3.4' ]
14
13
  database: [ 'mysql', 'postgresql', 'sqlite' ]
15
- exclude:
16
- - ruby: '2.4'
17
- bundler: '2.1.4'
18
- - ruby: '2.5'
19
- bundler: '2.1.4'
20
- - ruby: '2.6'
21
- bundler: '2.1.4'
22
- - ruby: '2.7'
23
- bundler: '1.17.3'
24
- - ruby: '3.0'
25
- bundler: '1.17.3'
26
- - ruby: '3.1'
27
- bundler: '1.17.3'
28
14
 
29
15
  services:
30
16
  postgres:
31
- image: postgres:13.5
17
+ image: postgres:16
32
18
  env:
33
19
  POSTGRES_USER: root
34
20
  POSTGRES_PASSWORD: gutentag
@@ -47,26 +33,16 @@ jobs:
47
33
 
48
34
  steps:
49
35
  - name: Check out code
50
- uses: actions/checkout@v2
36
+ uses: actions/checkout@v4
51
37
  - name: Set up ruby
52
38
  uses: ruby/setup-ruby@v1
53
39
  with:
54
40
  ruby-version: ${{ matrix.ruby }}
55
- bundler: ${{ matrix.bundler }}
56
41
  bundler-cache: true
57
-
58
- - name: Set up Bundler
59
- run: |
60
- export BUNDLER_VERSION=${{ matrix.bundler }}
61
- export BUNDLE_PATH=$PWD/vendor/bundle
62
-
63
- gem update --system
64
-
65
- bundle _${{ matrix.bundler }}_ config set path $PWD/$BUNDLE_PATH
66
- bundle _${{ matrix.bundler }}_ install --jobs=4 --retry=3
67
- bundle _${{ matrix.bundler }}_ update
68
- - name: Set up Appraisal
69
- run: bundle exec appraisal update
42
+ - name: Generate Appraisal gemfiles
43
+ run: bundle exec appraisal generate
44
+ - name: Install gems for each appraisal
45
+ run: bundle exec appraisal install
70
46
  - name: Test
71
47
  env:
72
48
  CI: "true"
@@ -77,16 +53,15 @@ jobs:
77
53
  run: bundle exec appraisal rspec
78
54
 
79
55
  rubocop:
80
- runs-on: ubuntu-18.04
56
+ runs-on: ubuntu-latest
81
57
 
82
58
  steps:
83
59
  - name: Check out code
84
- uses: actions/checkout@v2
60
+ uses: actions/checkout@v4
85
61
  - name: Set up ruby
86
62
  uses: ruby/setup-ruby@v1
87
63
  with:
88
- ruby-version: 2.7
89
- bundler: 2.1.4
64
+ ruby-version: 3.0
90
65
  bundler-cache: true
91
66
  - name: Rubocop
92
67
  run: bundle exec rubocop
data/.rubocop.yml CHANGED
@@ -4,7 +4,7 @@ inherit_from:
4
4
  require: rubocop-performance
5
5
 
6
6
  AllCops:
7
- TargetRubyVersion: 2.3
7
+ TargetRubyVersion: 3.0
8
8
  Exclude:
9
9
  - gemfiles/*.gemfile
10
10
  - spec/internal/db/migrate/*
data/Appraisals CHANGED
@@ -1,59 +1,51 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- appraise "rails_4_0" do
4
- gem "rails", "~> 4.0.13"
5
- gem "mysql2", "~> 0.3.10", :platform => :ruby
6
- end if RUBY_VERSION.to_f < 2.4
7
-
8
- appraise "rails_4_1" do
9
- gem "rails", "~> 4.1.16"
10
- gem "mysql2", "~> 0.3.13", :platform => :ruby
11
- end if RUBY_VERSION.to_f < 2.4
12
-
13
- appraise "rails_4_2" do
14
- gem "rails", "~> 4.2.8"
15
- gem "mysql2", "~> 0.4.0", :platform => :ruby
16
-
17
- gem "activerecord-jdbcmysql-adapter", "~> 1.3.23", :platform => :jruby
18
- gem "activerecord-jdbcpostgresql-adapter", "~> 1.3.23", :platform => :jruby
19
- gem "activerecord-jdbcsqlite3-adapter", "~> 1.3.23", :platform => :jruby
20
- end if RUBY_VERSION.to_f < 2.7
21
-
22
- appraise "rails_5_0" do
23
- gem "rails", "~> 5.0.3"
24
- gem "mysql2", "~> 0.4.0", :platform => :ruby
25
- end if RUBY_VERSION.to_f >= 2.2 && RUBY_VERSION.to_f <= 2.7
26
-
27
- appraise "rails_5_1" do
28
- gem "rails", "~> 5.1.1"
29
- gem "mysql2", "~> 0.4.0", :platform => :ruby
30
- end if RUBY_VERSION.to_f >= 2.2 && RUBY_VERSION.to_f <= 2.7
31
-
32
- appraise "rails_5_2" do
33
- gem "rails", "~> 5.2.0"
34
- gem "pg", "~> 1.0", :platform => :ruby
35
- gem "mysql2", "~> 0.5.0", :platform => :ruby
36
- end if RUBY_VERSION.to_f >= 2.2 && RUBY_VERSION.to_f <= 2.7
37
-
38
3
  if RUBY_PLATFORM != "java"
39
- appraise "rails_6_0" do
40
- gem "rails", "~> 6.0.0"
41
- gem "pg", "~> 1.0", :platform => :ruby
42
- gem "mysql2", "~> 0.5.0", :platform => :ruby
43
- gem "sqlite3", "~> 1.4", :platform => :ruby
44
- end if RUBY_VERSION.to_f >= 2.5 && RUBY_VERSION.to_f <= 3.0
45
-
46
4
  appraise "rails_6_1" do
47
- gem "rails", "~> 6.1.0"
48
- gem "pg", "~> 1.0", :platform => :ruby
49
- gem "mysql2", "~> 0.5.0", :platform => :ruby
50
- gem "sqlite3", "~> 1.4", :platform => :ruby
51
- end if RUBY_VERSION.to_f >= 2.5
5
+ gem "rails", "~> 6.1.0"
6
+ gem "rspec-rails", "~> 6.1"
7
+ gem "pg", "~> 1.0", :platform => :ruby
8
+ gem "mysql2", "~> 0.5.0", :platform => :ruby
9
+ gem "sqlite3", "~> 1.4", :platform => :ruby
10
+ end
52
11
 
53
12
  appraise "rails_7_0" do
54
- gem "rails", "~> 7.0.1"
55
- gem "pg", "~> 1.0", :platform => :ruby
56
- gem "mysql2", "~> 0.5.0", :platform => :ruby
57
- gem "sqlite3", "~> 1.4", :platform => :ruby
58
- end if RUBY_VERSION.to_f >= 2.7
13
+ gem "rails", "~> 7.0.8.6"
14
+ gem "rspec-rails", "~> 7.1"
15
+ gem "pg", "~> 1.0", :platform => :ruby
16
+ gem "mysql2", "~> 0.5.0", :platform => :ruby
17
+ gem "sqlite3", "~> 1.4", :platform => :ruby
18
+ end
19
+
20
+ appraise "rails_7_1" do
21
+ gem "rails", "~> 7.1.5"
22
+ gem "rspec-rails", "~> 7.1"
23
+ gem "pg", "~> 1.0", :platform => :ruby
24
+ gem "mysql2", "~> 0.5.0", :platform => :ruby
25
+ gem "sqlite3", "~> 2.0", :platform => :ruby
26
+ end if RUBY_VERSION.to_f >= 3.1
27
+
28
+ appraise "rails_7_2" do
29
+ gem "rails", "~> 7.2.2"
30
+ gem "rspec-rails", "~> 7.1"
31
+ gem "pg", "~> 1.0", :platform => :ruby
32
+ gem "mysql2", "~> 0.5.0", :platform => :ruby
33
+ gem "sqlite3", "~> 2.0", :platform => :ruby
34
+ end if RUBY_VERSION.to_f >= 3.1
35
+
36
+ appraise "rails_8_0" do
37
+ gem "rails", "~> 8.0.0"
38
+ gem "rspec-rails", "~> 8.0"
39
+ gem "pg", "~> 1.0", :platform => :ruby
40
+ gem "mysql2", "~> 0.5.0", :platform => :ruby
41
+ gem "sqlite3", "~> 2.3", :platform => :ruby
42
+ end if RUBY_VERSION.to_f >= 3.2
43
+
44
+ appraise "rails_8_1" do
45
+ gem "rails", "~> 8.1.0"
46
+ gem "rspec-rails", "~> 8.0"
47
+ gem "pg", "~> 1.0", :platform => :ruby
48
+ gem "mysql2", "~> 0.5.0", :platform => :ruby
49
+ gem "sqlite3", "~> 2.3", :platform => :ruby
50
+ end if RUBY_VERSION.to_f >= 3.2
59
51
  end
data/CHANGELOG.md CHANGED
@@ -2,6 +2,27 @@
2
2
 
3
3
  All notable changes to this project (at least, from v0.5.0 onwards) will be documented in this file.
4
4
 
5
+ ## 3.0.1 - 2025-11-24
6
+
7
+ ### Fixed
8
+
9
+ * Fixed dirty state after reload is called on a tagged instance. ([Michael Grosser](https://github.com/grosser) in [#54](https://github.com/pat/gutentag/pull/92))
10
+
11
+ ### Changed
12
+
13
+ * Updated syntax to be for Ruby 3.0 and newer.
14
+
15
+ ## 3.0.0 - 2025-11-21
16
+
17
+ ### Breaking
18
+
19
+ This release is all about which versions of Ruby and Rails are supported.
20
+
21
+ * Removing official support for Ruby 2.4-2.7 (2.7 may continue to work, but is not covered by CI).
22
+ * Removing official support for Rails 4.0-6.0 (5.2 and 6.0 may continue to work, but are not covered by CI).
23
+ * Adding official support for Ruby 3.2-3.4 (though no code changes were required for this).
24
+ * Adding official support for Rails 7.1-8.1 (one change from [Urban Hafner](https://github.com/ujh) in [#87](https://github.com/pat/gutentag/pull/87) assisted with this for Rails 8.0).
25
+
5
26
  ## 2.6.2 - 2022-11-05
6
27
 
7
28
  ### Fixed
data/Gemfile CHANGED
@@ -4,22 +4,24 @@ source "https://rubygems.org"
4
4
 
5
5
  gemspec
6
6
 
7
- gem "test-unit", :platform => :ruby_22
8
-
9
- gem "mysql2", "~> 0.3", :platform => :ruby
10
- gem "pg", "~> 0.18", :platform => :ruby
7
+ gem "mysql2", "~> 0.5", :platform => :ruby
8
+ gem "pg", "~> 1.0", :platform => :ruby
11
9
 
12
10
  if RUBY_VERSION.to_f < 3.0
13
11
  gem "sqlite3", "~> 1.3.13"
14
12
  else
15
- gem "sqlite3", "~> 1.4"
13
+ gem "sqlite3", ">= 1.4"
16
14
  end
17
15
 
18
16
  gem "activerecord-jdbcmysql-adapter", ">= 1.3.23", :platform => :jruby
19
17
  gem "activerecord-jdbcpostgresql-adapter", ">= 1.3.23", :platform => :jruby
20
18
  gem "activerecord-jdbcsqlite3-adapter", ">= 1.3.23", :platform => :jruby
21
19
 
22
- gem "activerecord", [">= 3.2.22"] if RUBY_PLATFORM == "java"
20
+ gem "activerecord", [">= 5.2"] if RUBY_PLATFORM == "java"
23
21
 
24
22
  # Required for testing Rails 6.1 on MRI 3.1+
25
23
  gem "net-smtp" if RUBY_VERSION.to_f > 3.0
24
+ # mutex_m is no longer a default gem in MRI 3.4, warnings in 3.3
25
+ gem "mutex_m" if RUBY_VERSION.to_f > 3.2
26
+ # drb is no longer a default gem in MRI 4.0, warnings in 3.4
27
+ gem "drb" if RUBY_VERSION.to_f > 3.3
data/README.md CHANGED
@@ -93,19 +93,21 @@ Gutentag::Tag.names_for_scope(Article.order(created_at: :desc).limit(2))
93
93
 
94
94
  ### Dependencies
95
95
 
96
- These are the versions the test suite runs against. It's possible it may work on older versions of Ruby, but it definitely won't work on older versions of Rails.
96
+ These are the versions the current test suite runs against. It's possible that the gem may work on slightly older versions (Ruby 2.7, Rails 5.2).
97
97
 
98
- * Ruby: MRI v2.3-v3.1, JRuby v9.2.5
99
- * Rails/ActiveRecord: v4.0-v7.0
98
+ * Ruby: MRI v3.0-v3.4
99
+ * Rails/ActiveRecord: v6.1-v8.1
100
100
 
101
- If you're using MRI v2.2 and/or ActiveRecord v3.2, the last version of Gutentag that fully supported those versions is v2.4.1.
101
+ If you're using Ruby v2.4-2.7 and/or ActiveRecord v4.0-6.0, the last release of Gutentag that officially supported those versions is v2.6.2, though the v3.0.0 release may be fine.
102
+
103
+ If you're using Ruby v2.2 and/or ActiveRecord v3.2, the last release of Gutentag that fully supported those versions is v2.4.1.
102
104
 
103
105
  ### Installing
104
106
 
105
107
  Get it into your Gemfile - and don't forget the version constraint!
106
108
 
107
109
  ```Ruby
108
- gem 'gutentag', '~> 2.6'
110
+ gem 'gutentag', '~> 3.0'
109
111
  ```
110
112
 
111
113
  Next: your tags get persisted to your database, so let's import the migrations, update them to your current version of Rails, and then migrate:
@@ -194,4 +196,4 @@ Please note that this project now has a [Contributor Code of Conduct](http://con
194
196
 
195
197
  <h2 id="licence">Licence</h2>
196
198
 
197
- Copyright (c) 2013-2022, Gutentag is developed and maintained by Pat Allan, and is released under the open MIT Licence.
199
+ Copyright (c) 2013-2025, Gutentag is developed and maintained by Pat Allan, and is released under the open MIT Licence.
@@ -33,7 +33,7 @@ class Gutentag::Tag < ActiveRecord::Base
33
33
  end
34
34
 
35
35
  def name=(value)
36
- super(Gutentag.normaliser.call(value))
36
+ write_attribute(:name, Gutentag.normaliser.call(value))
37
37
  end
38
38
  end
39
39
 
data/gutentag.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "gutentag"
5
- s.version = "2.6.2"
5
+ s.version = "3.0.1"
6
6
  s.authors = ["Pat Allan"]
7
7
  s.email = ["pat@freelancing-gods.com"]
8
8
  s.homepage = "https://github.com/pat/gutentag"
@@ -14,14 +14,16 @@ Gem::Specification.new do |s|
14
14
  s.test_files = `git ls-files -- {spec}/*`.split("\n")
15
15
  s.require_paths = ["lib"]
16
16
 
17
+ s.required_ruby_version = ">= 3.0.0"
18
+
17
19
  s.add_runtime_dependency "activerecord", ">= 3.2.0"
18
20
 
19
- s.add_development_dependency "appraisal", "~> 2.4.1"
21
+ s.add_development_dependency "appraisal", "~> 2.5.0"
20
22
  s.add_development_dependency "bundler", ">= 1.17"
21
23
  s.add_development_dependency "combustion", "~> 1.1"
22
- s.add_development_dependency "database_cleaner", "~> 1.6"
24
+ s.add_development_dependency "database_cleaner", "~> 2.1"
23
25
  s.add_development_dependency "rails"
24
- s.add_development_dependency "rspec-rails", "~> 3.1"
25
- s.add_development_dependency "rubocop", "~> 0.81.0"
26
- s.add_development_dependency "rubocop-performance", "~> 1"
26
+ s.add_development_dependency "rspec-rails", ">= 5.1.2"
27
+ s.add_development_dependency "rubocop", "~> 1.81.7"
28
+ s.add_development_dependency "rubocop-performance", "~> 1.26"
27
29
  end
@@ -4,20 +4,4 @@ module Gutentag::ActiveRecord::ClassMethods
4
4
  def tagged_with(options)
5
5
  Gutentag::TaggedWith.call self, options
6
6
  end
7
-
8
- if ActiveRecord::VERSION::STRING.to_f < 4.2
9
- def skip_time_zone_conversion_for_attributes
10
- super + [:tag_names]
11
- end
12
- end
13
-
14
- if ActiveRecord::VERSION::STRING.to_f < 4.0
15
- def create_time_zone_conversion_attribute?(attr_name, column)
16
- attr_name != "tag_names" && super
17
- end
18
-
19
- def attribute_cast_code(attr_name)
20
- attr_name == "tag_names" ? "v" : super
21
- end
22
- end
23
7
  end
@@ -11,12 +11,7 @@ module Gutentag::ActiveRecord::InstanceMethods
11
11
  # the instance directly (e.g. article.tags << tag), which invokes the save
12
12
  # callbacks, but the old tag_names value is stored but not updated.
13
13
  def reset_tag_names
14
- # Rails 5.1 introduces major changes to how ActiveModel::Dirty works:
15
- # https://github.com/pat/gutentag/pull/70#issuecomment-524605448
16
- # For Rails <5.1 we'll use *_previously_changed?
17
- # and for 5.1+ we'll use saved_change_to_*?
18
- return if AR_VERSION < 5.1 && tag_names_previously_changed?
19
- return if AR_VERSION >= 5.1 && saved_change_to_tag_names?
14
+ return if saved_change_to_tag_names?
20
15
 
21
16
  # Update the underlying value rather than going through the setter, to
22
17
  # ensure this update doesn't get marked as a 'change'.
@@ -47,6 +42,11 @@ module Gutentag::ActiveRecord::InstanceMethods
47
42
  super Gutentag::TagNames.call(names)
48
43
  end
49
44
 
45
+ def reload(*)
46
+ @prepared_tag_names = false
47
+ super
48
+ end
49
+
50
50
  private
51
51
 
52
52
  def persist_tags
@@ -31,45 +31,20 @@ class Gutentag::ActiveRecord
31
31
  end
32
32
 
33
33
  def add_attribute
34
- if ActiveRecord::VERSION::STRING.to_f <= 4.2
35
- model.define_attribute_method "tag_names"
36
- else
37
- model.attribute "tag_names", ActiveRecord::Type::Value.new,
38
- :default => default_tag_names
39
- end
34
+ model.attribute "tag_names", ActiveRecord::Type::Value.new,
35
+ :default => nil
40
36
  end
41
37
 
42
38
  def add_callbacks
43
39
  model.after_save :persist_tags
44
-
45
- if legacy?
46
- model.after_save :reset_tag_names
47
- else
48
- model.after_commit :reset_tag_names, :on => %i[ create update ]
49
- end
40
+ model.after_commit :reset_tag_names, :on => %i[ create update ]
50
41
  end
51
42
 
52
43
  def add_methods
53
- case ActiveRecord::VERSION::STRING.to_f
54
- when 3.2..4.1
55
- require "gutentag/active_record/instance_methods_3_2"
56
- when 4.2
57
- require "gutentag/active_record/instance_methods_4_2"
58
- else
59
- require "gutentag/active_record/instance_methods"
60
- end
61
-
62
44
  model.send :extend, Gutentag::ActiveRecord::ClassMethods
63
45
  model.send :include, Gutentag::ActiveRecord::InstanceMethods
64
46
  end
65
-
66
- def default_tag_names
67
- ActiveRecord::VERSION::STRING.to_f <= 4.2 ? [] : nil
68
- end
69
-
70
- def legacy?
71
- ActiveRecord::VERSION::STRING.to_f < 4.2
72
- end
73
47
  end
74
48
 
75
49
  require "gutentag/active_record/class_methods"
50
+ require "gutentag/active_record/instance_methods"
@@ -10,10 +10,6 @@ module Gutentag
10
10
  def update_migration_versions
11
11
  superclass = "ActiveRecord::Migration[#{rails_version}]"
12
12
 
13
- if ::ActiveRecord::VERSION::MAJOR < 5
14
- superclass = "ActiveRecord::Migration"
15
- end
16
-
17
13
  migration_files.each do |file|
18
14
  gsub_file file,
19
15
  /< ActiveRecord::Migration\[4\.2\]$/,
@@ -32,11 +28,10 @@ module Gutentag
32
28
  end
33
29
 
34
30
  def known_migration_names
35
- @known_migration_names ||= begin
31
+ @known_migration_names ||=
36
32
  Dir[File.join(__dir__, "../../../db/migrate/*.rb")].collect do |path|
37
- File.basename(path).gsub(/\A\d+_/, "").gsub(/\.rb\z/, "")
33
+ File.basename(path).gsub(/\A\d+_/, "").delete_suffix(".rb")
38
34
  end
39
- end
40
35
  end
41
36
 
42
37
  def rails_version
@@ -9,10 +9,7 @@ class Gutentag::TagValidations
9
9
  :uniqueness => {:case_sensitive => false}
10
10
  }.freeze
11
11
  DATABASE_ERROR_CLASSES = lambda {
12
- classes = []
13
- if ActiveRecord::VERSION::STRING.to_f > 4.0
14
- classes << ActiveRecord::NoDatabaseError
15
- end
12
+ classes = [ActiveRecord::NoDatabaseError]
16
13
  classes << ActiveRecord::ConnectionNotEstablished
17
14
  classes << Mysql2::Error if defined?(::Mysql2)
18
15
  classes << PG::ConnectionBad if defined?(::PG)
data/lib/gutentag.rb CHANGED
@@ -3,14 +3,6 @@
3
3
  require "active_record/version"
4
4
 
5
5
  module Gutentag
6
- def self.dirtier
7
- @dirtier
8
- end
9
-
10
- def self.dirtier=(dirtier)
11
- @dirtier = dirtier
12
- end
13
-
14
6
  def self.normaliser
15
7
  @normaliser ||= lambda { |tag_name| tag_name.to_s.downcase }
16
8
  end
@@ -30,14 +22,11 @@ end
30
22
 
31
23
  require "gutentag/active_record"
32
24
  require "gutentag/change_state"
33
- require "gutentag/dirty"
34
25
  require "gutentag/persistence"
35
26
  require "gutentag/remove_unused"
36
27
  require "gutentag/tag_names"
37
28
  require "gutentag/tagged_with"
38
29
 
39
- Gutentag.dirtier = Gutentag::Dirty if ActiveRecord::VERSION::STRING.to_f < 4.2
40
-
41
30
  if defined?(Rails::Engine)
42
31
  require "gutentag/engine"
43
32
  else
@@ -12,17 +12,11 @@ RSpec.describe "Dirty state of tag names" do
12
12
  expect(article.tag_names_changed?).to eq(true)
13
13
  expect(article.tag_names_was).to eq([])
14
14
  expect(article.tag_names_change).to eq([[], ["pancakes"]])
15
-
16
- if ActiveRecord::VERSION::STRING.to_f > 4.0
17
- expect(article.tag_names_changed?(:from => [], :to => ["pancakes"])).
18
- to eq(true)
19
- end
20
-
21
- if ActiveRecord::VERSION::STRING.to_f > 5.0
22
- expect(article.will_save_change_to_tag_names?).to eq(true)
23
- expect(article.tag_names_change_to_be_saved).to eq([[], ["pancakes"]])
24
- expect(article.tag_names_in_database).to eq([])
25
- end
15
+ expect(article.tag_names_changed?(:from => [], :to => ["pancakes"])).
16
+ to eq(true)
17
+ expect(article.will_save_change_to_tag_names?).to eq(true)
18
+ expect(article.tag_names_change_to_be_saved).to eq([[], ["pancakes"]])
19
+ expect(article.tag_names_in_database).to eq([])
26
20
  end
27
21
 
28
22
  it "knows what tag names have changed" do
@@ -34,20 +28,14 @@ RSpec.describe "Dirty state of tag names" do
34
28
  expect(article).to_not be_changed
35
29
  expect(article.tag_names_changed?).to eq(false)
36
30
  expect(article.previous_changes["tag_names"]).to eq([[], ["pancakes"]])
37
-
38
- if ActiveRecord::VERSION::STRING.to_f >= 5.0
39
- expect(article.tag_names_previously_changed?).to eq(true)
40
- expect(article.tag_names_previous_change).to eq([[], ["pancakes"]])
41
- end
42
-
43
- if ActiveRecord::VERSION::STRING.to_f > 5.0
44
- expect(article.saved_change_to_tag_names?).to eq(true)
45
- expect(article.saved_change_to_tag_names).to eq([[], ["pancakes"]])
46
- expect(article.saved_changes["tag_names"]).to eq([[], ["pancakes"]])
47
- expect(article.tag_names_before_last_save).to eq([])
48
- expect(article.tag_names_change_to_be_saved).to eq(nil)
49
- expect(article.tag_names_in_database).to eq(["pancakes"])
50
- end
31
+ expect(article.tag_names_previously_changed?).to eq(true)
32
+ expect(article.tag_names_previous_change).to eq([[], ["pancakes"]])
33
+ expect(article.saved_change_to_tag_names?).to eq(true)
34
+ expect(article.saved_change_to_tag_names).to eq([[], ["pancakes"]])
35
+ expect(article.saved_changes["tag_names"]).to eq([[], ["pancakes"]])
36
+ expect(article.tag_names_before_last_save).to eq([])
37
+ expect(article.tag_names_change_to_be_saved).to eq(nil)
38
+ expect(article.tag_names_in_database).to eq(["pancakes"])
51
39
  end
52
40
 
53
41
  it "knows when tags have not changed" do
@@ -57,4 +45,16 @@ RSpec.describe "Dirty state of tag names" do
57
45
  article.tag_names = ["pancakes"]
58
46
  expect(article.changes).to eq({})
59
47
  end
48
+
49
+ it "knows when a saved instance is reloaded (and thus has no changes)" do
50
+ article.update!(:tag_names => ["pancakes"])
51
+ article.reload
52
+ article.tag_names = ["pancakes"]
53
+
54
+ expect(article).not_to be_changed
55
+ expect(article.changes).to eq({})
56
+ expect(article.tag_names_changed?).to eq(false)
57
+ expect(article.tag_names_was).to eq(["pancakes"])
58
+ expect(article.tag_names_change).to eq(nil)
59
+ end
60
60
  end
@@ -21,7 +21,7 @@ RSpec.describe "Managing tags via names" do
21
21
  end
22
22
 
23
23
  it "allows for different tag normalisation" do
24
- Gutentag.normaliser = lambda { |name| name.upcase }
24
+ Gutentag.normaliser = lambda(&:upcase)
25
25
 
26
26
  tag = Gutentag::Tag.create(:name => "melbourne")
27
27
  expect(tag.name).to eq("MELBOURNE")
@@ -64,12 +64,9 @@ RSpec.describe Gutentag::Tag, :type => :model do
64
64
  expect(tag.errors[:name].length).to eq(1)
65
65
  end
66
66
 
67
- if ENV["DATABASE"] == "mysql" || (
68
- Gem::Version.new(Rails.version) < Gem::Version.new("4.2.0")
69
- )
70
- # When using MySQL or Rails before 4.2, string columns convert to
71
- # VARCHAR(255), therefore the column has a limit of 255, even though we
72
- # did not specify a limit
67
+ if ENV["DATABASE"] == "mysql"
68
+ # When using MySQL, string columns convert to VARCHAR(255), therefore the
69
+ # column has a limit of 255, even though we did not specify a limit.
73
70
  it "validates the length of the name" do
74
71
  tag = Gutentag::Tag.create(:name => "a" * 256)
75
72
  expect(tag.errors[:name].length).to eq(1)
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "bundler/setup"
4
+ require "logger"
4
5
 
5
6
  Bundler.require :default, :development
6
7
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gutentag
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.6.2
4
+ version: 3.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pat Allan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-05 00:00:00.000000000 Z
11
+ date: 2025-11-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 2.4.1
33
+ version: 2.5.0
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 2.4.1
40
+ version: 2.5.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '1.6'
75
+ version: '2.1'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '1.6'
82
+ version: '2.1'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rails
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -98,44 +98,44 @@ dependencies:
98
98
  name: rspec-rails
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - "~>"
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
- version: '3.1'
103
+ version: 5.1.2
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - "~>"
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
- version: '3.1'
110
+ version: 5.1.2
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: rubocop
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: 0.81.0
117
+ version: 1.81.7
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: 0.81.0
124
+ version: 1.81.7
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: rubocop-performance
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: '1'
131
+ version: '1.26'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: '1'
138
+ version: '1.26'
139
139
  description: A good, simple, solid tagging extension for ActiveRecord
140
140
  email:
141
141
  - pat@freelancing-gods.com
@@ -164,10 +164,7 @@ files:
164
164
  - lib/gutentag/active_record.rb
165
165
  - lib/gutentag/active_record/class_methods.rb
166
166
  - lib/gutentag/active_record/instance_methods.rb
167
- - lib/gutentag/active_record/instance_methods_3_2.rb
168
- - lib/gutentag/active_record/instance_methods_4_2.rb
169
167
  - lib/gutentag/change_state.rb
170
- - lib/gutentag/dirty.rb
171
168
  - lib/gutentag/engine.rb
172
169
  - lib/gutentag/generators/migration_versions_generator.rb
173
170
  - lib/gutentag/persistence.rb
@@ -195,7 +192,6 @@ files:
195
192
  - spec/models/gutentag/tagging_spec.rb
196
193
  - spec/spec_helper.rb
197
194
  - spec/support/adjust_migrations.rb
198
- - spec/support/mysql.rb
199
195
  homepage: https://github.com/pat/gutentag
200
196
  licenses:
201
197
  - MIT
@@ -208,14 +204,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
208
204
  requirements:
209
205
  - - ">="
210
206
  - !ruby/object:Gem::Version
211
- version: '0'
207
+ version: 3.0.0
212
208
  required_rubygems_version: !ruby/object:Gem::Requirement
213
209
  requirements:
214
210
  - - ">="
215
211
  - !ruby/object:Gem::Version
216
212
  version: '0'
217
213
  requirements: []
218
- rubygems_version: 3.3.3
214
+ rubygems_version: 3.5.22
219
215
  signing_key:
220
216
  specification_version: 4
221
217
  summary: Good Tags
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # For Rails <= 4.1
4
- module Gutentag::ActiveRecord::InstanceMethods
5
- # The reason we overwrite the stored value is because new tags may be added to
6
- # the instance directly (e.g. article.tags << tag), which invokes the save
7
- # callbacks, but the old tag_names value is stored but not updated.
8
- def reset_tag_names
9
- @tag_names = nil
10
- end
11
-
12
- def tag_names
13
- @tag_names ||= tags.pluck(:name)
14
- end
15
-
16
- def tag_names=(names)
17
- names = Gutentag::TagNames.call(names)
18
-
19
- Gutentag.dirtier.call self, names if Gutentag.dirtier.present?
20
-
21
- @tag_names = names
22
- end
23
-
24
- private
25
-
26
- def persist_tags
27
- Gutentag::Persistence.new(Gutentag::ChangeState.new(self)).persist
28
- end
29
- end
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # For Rails 4.2 only.
4
- module Gutentag::ActiveRecord::InstanceMethods
5
- # The reason we overwrite the stored value is because new tags may be added to
6
- # the instance directly (e.g. article.tags << tag), which invokes the save
7
- # callbacks, but the old tag_names value is stored but not updated.
8
- def reset_tag_names
9
- # Update the underlying value rather than going through the setter, to
10
- # ensure this update doesn't get marked as a 'change'.
11
- @tag_names = nil
12
- end
13
-
14
- def tag_names
15
- @tag_names ||= begin
16
- raw = tags.pluck(:name)
17
- raw_write_attribute "tag_names", raw
18
- raw
19
- end
20
- end
21
-
22
- def tag_names=(names)
23
- new_names = Gutentag::TagNames.call names
24
- return if new_names.sort == tag_names.sort
25
-
26
- tag_names_will_change!
27
-
28
- write_attribute "tag_names", new_names
29
- @tag_names = new_names
30
- end
31
-
32
- private
33
-
34
- def persist_tags
35
- Gutentag::Persistence.new(Gutentag::ChangeState.new(self)).persist
36
- end
37
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Gutentag::Dirty
4
- def self.call(instance, tag_names)
5
- new(instance, tag_names).call
6
- end
7
-
8
- def initialize(instance, tag_names)
9
- @instance = instance
10
- @tag_names = tag_names
11
- end
12
-
13
- def call
14
- return unless changes.present?
15
-
16
- instance.tag_names_will_change!
17
- instance.changed_attributes[:tag_names] = existing
18
- end
19
-
20
- private
21
-
22
- attr_reader :instance, :tag_names
23
-
24
- def changes
25
- (existing + tag_names).uniq - (existing & tag_names)
26
- end
27
-
28
- def existing
29
- instance.tag_names
30
- end
31
- end
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "active_record"
4
-
5
- # New versions of MySQL don't allow NULL values for primary keys, but old
6
- # versions of Rails do. To use both at the same time, we need to update Rails'
7
- # default primary key type to no longer have a default NULL value.
8
- #
9
- class PatchAdapter
10
- def call
11
- return unless using_mysql? && using_rails_pre_4_1?
12
-
13
- require "active_record/connection_adapters/abstract_mysql_adapter"
14
- ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter::
15
- NATIVE_DATABASE_TYPES[:primary_key] = "int(11) auto_increment PRIMARY KEY"
16
- end
17
-
18
- def using_mysql?
19
- ENV.fetch("DATABASE", "sqlite") == "mysql"
20
- end
21
-
22
- def using_rails_pre_4_1?
23
- ActiveRecord::VERSION::STRING.to_f < 4.1
24
- end
25
- end
26
-
27
- PatchAdapter.new.call