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 +4 -4
- data/.github/workflows/ci.yml +12 -37
- data/.rubocop.yml +1 -1
- data/Appraisals +44 -52
- data/CHANGELOG.md +21 -0
- data/Gemfile +8 -6
- data/README.md +8 -6
- data/app/models/gutentag/tag.rb +1 -1
- data/gutentag.gemspec +8 -6
- data/lib/gutentag/active_record/class_methods.rb +0 -16
- data/lib/gutentag/active_record/instance_methods.rb +6 -6
- data/lib/gutentag/active_record.rb +4 -29
- data/lib/gutentag/generators/migration_versions_generator.rb +2 -7
- data/lib/gutentag/tag_validations.rb +1 -4
- data/lib/gutentag.rb +0 -11
- data/spec/acceptance/dirty_state_spec.rb +25 -25
- data/spec/acceptance/tag_names_spec.rb +1 -1
- data/spec/models/gutentag/tag_spec.rb +3 -6
- data/spec/spec_helper.rb +1 -0
- metadata +16 -20
- data/lib/gutentag/active_record/instance_methods_3_2.rb +0 -29
- data/lib/gutentag/active_record/instance_methods_4_2.rb +0 -37
- data/lib/gutentag/dirty.rb +0 -31
- data/spec/support/mysql.rb +0 -27
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5afcb64119c9fff07b6c4cb8786da632f3ad66d230ea049b45b7780440b9692a
|
|
4
|
+
data.tar.gz: ed0b54305d58152e70ec3de7b5cc324c5a443a1b0f73ade5e136cedb785b77f0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4457511634f9ffee17502b8deab34ff6a306750dc0886864cd913c68f0e60c52873a4716ef6941ee23955477ca5b72847b3d644d8dfca6e0ccc16a8d7e27bf6f
|
|
7
|
+
data.tar.gz: 355801ea0a573f02a509ece9c9175786672c79d457e7ed5935ca6b73552a9fcc6cad065c9c65bb42b29adce1958957f73ef5dc1ef7244ac65dedfdcae7f4c772
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -1,34 +1,20 @@
|
|
|
1
1
|
name: CI
|
|
2
2
|
|
|
3
|
-
on: [push
|
|
3
|
+
on: [push]
|
|
4
4
|
|
|
5
5
|
jobs:
|
|
6
6
|
test:
|
|
7
|
-
runs-on: ubuntu-
|
|
7
|
+
runs-on: ubuntu-22.04
|
|
8
8
|
|
|
9
9
|
strategy:
|
|
10
10
|
fail-fast: false
|
|
11
11
|
matrix:
|
|
12
|
-
ruby: [ '
|
|
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:
|
|
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@
|
|
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
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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-
|
|
56
|
+
runs-on: ubuntu-latest
|
|
81
57
|
|
|
82
58
|
steps:
|
|
83
59
|
- name: Check out code
|
|
84
|
-
uses: actions/checkout@
|
|
60
|
+
uses: actions/checkout@v4
|
|
85
61
|
- name: Set up ruby
|
|
86
62
|
uses: ruby/setup-ruby@v1
|
|
87
63
|
with:
|
|
88
|
-
ruby-version:
|
|
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
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",
|
|
48
|
-
gem "
|
|
49
|
-
gem "
|
|
50
|
-
gem "
|
|
51
|
-
|
|
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",
|
|
55
|
-
gem "
|
|
56
|
-
gem "
|
|
57
|
-
gem "
|
|
58
|
-
|
|
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 "
|
|
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", "
|
|
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", [">=
|
|
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
|
|
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
|
|
99
|
-
* Rails/ActiveRecord:
|
|
98
|
+
* Ruby: MRI v3.0-v3.4
|
|
99
|
+
* Rails/ActiveRecord: v6.1-v8.1
|
|
100
100
|
|
|
101
|
-
If you're using
|
|
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', '~>
|
|
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-
|
|
199
|
+
Copyright (c) 2013-2025, Gutentag is developed and maintained by Pat Allan, and is released under the open MIT Licence.
|
data/app/models/gutentag/tag.rb
CHANGED
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 = "
|
|
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.
|
|
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
|
|
24
|
+
s.add_development_dependency "database_cleaner", "~> 2.1"
|
|
23
25
|
s.add_development_dependency "rails"
|
|
24
|
-
s.add_development_dependency "rspec-rails", "
|
|
25
|
-
s.add_development_dependency "rubocop", "~>
|
|
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
|
-
|
|
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
|
-
|
|
35
|
-
|
|
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 ||=
|
|
31
|
+
@known_migration_names ||=
|
|
36
32
|
Dir[File.join(__dir__, "../../../db/migrate/*.rb")].collect do |path|
|
|
37
|
-
File.basename(path).gsub(/\A\d+_/, "").
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
|
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
|
-
|
|
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
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:
|
|
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:
|
|
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.
|
|
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.
|
|
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
|
|
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
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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.
|
|
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
|
data/lib/gutentag/dirty.rb
DELETED
|
@@ -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
|
data/spec/support/mysql.rb
DELETED
|
@@ -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
|