gutentag 2.1.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/README.md +1 -1
- data/app/models/gutentag/tag.rb +2 -6
- data/gutentag.gemspec +7 -6
- data/lib/gutentag.rb +1 -5
- data/lib/gutentag/active_record.rb +50 -3
- data/lib/gutentag/active_record/class_methods.rb +16 -0
- data/lib/gutentag/active_record/{instance_methods.rb → legacy_instance_methods.rb} +2 -1
- data/lib/gutentag/active_record/modern_instance_methods.rb +26 -0
- data/lib/gutentag/dirty.rb +4 -1
- data/lib/gutentag/persistence.rb +0 -2
- data/spec/acceptance/dirty_state_spec.rb +52 -0
- data/spec/acceptance/tag_names_spec.rb +1 -20
- data/spec/spec_helper.rb +13 -2
- metadata +20 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e6935bb3c51e7b225573d2330a1f95b858bed7cd130f0825177aef98c9f0d175
|
4
|
+
data.tar.gz: 52201a047a523da00bd33cee60fe72ac1901c1273eb8296b4cfa637349991cf2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 75251e4214a914b48256c60a97241f0db275fd06441e4eb3def15a8ada9fdebf6150208237b81d6715d63c87eae15d2bbcca208c61cc767961f451be60c8737f
|
7
|
+
data.tar.gz: 2b8f4b94045a63adfae0bb8e762922f788e49d3b0f37e44d5f54f8a2cd5fb0390f453a532106cc6b4da38b4f9c5cd8bf51211f2ba64713b0fb649a35b5b71e5d
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,16 @@
|
|
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
|
+
## 2.2.0 - 2018-03-04
|
6
|
+
|
7
|
+
### Added
|
8
|
+
|
9
|
+
* Dirty state support for `tag_names` is now available for Rails 4.2 onwards, and is more reliable for Rails 3.2-4.1 (supporting all known methods, such as `tag_names_changed?`, `previous_changes`, etc.)
|
10
|
+
|
11
|
+
### Changed
|
12
|
+
|
13
|
+
* Switch normalising of tag names from a callback within `Gutentag::Tag` to `#name=` ([Tomasz Ras](https://github.com/RasMachineMan) in [#47](https://github.com/pat/gutentag/pull/47)).
|
14
|
+
|
5
15
|
## 2.1.0 - 2018-02-01
|
6
16
|
|
7
17
|
### Added
|
data/README.md
CHANGED
@@ -80,7 +80,7 @@ These are the versions the test suite runs against. It's possible it may work on
|
|
80
80
|
Get it into your Gemfile - and don't forget the version constraint!
|
81
81
|
|
82
82
|
```Ruby
|
83
|
-
gem 'gutentag', '~> 2.
|
83
|
+
gem 'gutentag', '~> 2.2.0'
|
84
84
|
```
|
85
85
|
|
86
86
|
Next: your tags get persisted to your database, so let's import and run the migrations to get the tables set up:
|
data/app/models/gutentag/tag.rb
CHANGED
@@ -11,8 +11,6 @@ class Gutentag::Tag < ActiveRecord::Base
|
|
11
11
|
|
12
12
|
scope :by_weight, lambda { order("gutentag_tags.taggings_count DESC") }
|
13
13
|
|
14
|
-
before_validation :normalise_name
|
15
|
-
|
16
14
|
def self.find_by_name(name)
|
17
15
|
where(:name => Gutentag.normaliser.call(name)).first
|
18
16
|
end
|
@@ -21,9 +19,7 @@ class Gutentag::Tag < ActiveRecord::Base
|
|
21
19
|
find_by_name(name) || create(:name => name)
|
22
20
|
end
|
23
21
|
|
24
|
-
|
25
|
-
|
26
|
-
def normalise_name
|
27
|
-
self.name = Gutentag.normaliser.call name
|
22
|
+
def name=(value)
|
23
|
+
super(Gutentag.normaliser.call(value))
|
28
24
|
end
|
29
25
|
end
|
data/gutentag.gemspec
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "gutentag"
|
6
|
-
s.version = "2.
|
6
|
+
s.version = "2.2.0"
|
7
7
|
s.authors = ["Pat Allan"]
|
8
8
|
s.email = ["pat@freelancing-gods.com"]
|
9
9
|
s.homepage = "https://github.com/pat/gutentag"
|
@@ -17,10 +17,11 @@ Gem::Specification.new do |s|
|
|
17
17
|
|
18
18
|
s.add_runtime_dependency "activerecord", ">= 3.2.0"
|
19
19
|
|
20
|
-
s.add_development_dependency "appraisal",
|
21
|
-
s.add_development_dependency "bundler",
|
22
|
-
s.add_development_dependency "combustion",
|
20
|
+
s.add_development_dependency "appraisal", "~> 2.1.0"
|
21
|
+
s.add_development_dependency "bundler", ">= 1.7.12"
|
22
|
+
s.add_development_dependency "combustion", "0.8.0"
|
23
|
+
s.add_development_dependency "database_cleaner", "~> 1.6"
|
23
24
|
s.add_development_dependency "rails"
|
24
|
-
s.add_development_dependency "rspec-rails",
|
25
|
-
s.add_development_dependency "rubocop",
|
25
|
+
s.add_development_dependency "rspec-rails", "~> 3.1"
|
26
|
+
s.add_development_dependency "rubocop", "~> 0.52.1"
|
26
27
|
end
|
data/lib/gutentag.rb
CHANGED
@@ -36,11 +36,7 @@ require "gutentag/remove_unused"
|
|
36
36
|
require "gutentag/tag_validations"
|
37
37
|
require "gutentag/tagged_with"
|
38
38
|
|
39
|
-
if ActiveRecord::VERSION::
|
40
|
-
Gutentag.dirtier = Gutentag::Dirty
|
41
|
-
elsif ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR < 2
|
42
|
-
Gutentag.dirtier = Gutentag::Dirty
|
43
|
-
end
|
39
|
+
Gutentag.dirtier = Gutentag::Dirty if ActiveRecord::VERSION::STRING.to_f < 4.2
|
44
40
|
|
45
41
|
require "active_support/lazy_load_hooks"
|
46
42
|
ActiveSupport.on_load(:gutentag) do
|
@@ -2,6 +2,25 @@
|
|
2
2
|
|
3
3
|
class Gutentag::ActiveRecord
|
4
4
|
def self.call(model)
|
5
|
+
new(model).call
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize(model)
|
9
|
+
@model = model
|
10
|
+
end
|
11
|
+
|
12
|
+
def call
|
13
|
+
add_associations
|
14
|
+
add_callbacks
|
15
|
+
add_methods
|
16
|
+
add_attribute
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
attr_reader :model
|
22
|
+
|
23
|
+
def add_associations
|
5
24
|
model.has_many :taggings,
|
6
25
|
:class_name => "Gutentag::Tagging",
|
7
26
|
:as => :taggable,
|
@@ -9,13 +28,41 @@ class Gutentag::ActiveRecord
|
|
9
28
|
model.has_many :tags,
|
10
29
|
:class_name => "Gutentag::Tag",
|
11
30
|
:through => :taggings
|
31
|
+
end
|
32
|
+
|
33
|
+
def add_attribute
|
34
|
+
if legacy?
|
35
|
+
model.define_attribute_method "tag_names"
|
36
|
+
else
|
37
|
+
model.attribute "tag_names", ActiveRecord::Type::Value.new, :default => []
|
38
|
+
end
|
39
|
+
end
|
12
40
|
|
41
|
+
def add_callbacks
|
13
42
|
model.after_save :persist_tags
|
14
43
|
|
15
|
-
|
16
|
-
|
44
|
+
if legacy?
|
45
|
+
model.after_save :reset_tag_names
|
46
|
+
else
|
47
|
+
model.after_commit :reset_tag_names, :on => %i[ create update ]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def add_methods
|
52
|
+
model.send :extend, Gutentag::ActiveRecord::ClassMethods
|
53
|
+
|
54
|
+
if legacy?
|
55
|
+
model.send :include, Gutentag::ActiveRecord::LegacyInstanceMethods
|
56
|
+
else
|
57
|
+
model.send :include, Gutentag::ActiveRecord::ModernInstanceMethods
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def legacy?
|
62
|
+
ActiveRecord::VERSION::STRING.to_f < 4.2
|
17
63
|
end
|
18
64
|
end
|
19
65
|
|
20
66
|
require "gutentag/active_record/class_methods"
|
21
|
-
require "gutentag/active_record/
|
67
|
+
require "gutentag/active_record/legacy_instance_methods"
|
68
|
+
require "gutentag/active_record/modern_instance_methods"
|
@@ -4,4 +4,20 @@ 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
|
7
23
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# For Rails 4.2+
|
4
|
+
module Gutentag::ActiveRecord::ModernInstanceMethods
|
5
|
+
def reset_tag_names
|
6
|
+
self.tag_names = nil
|
7
|
+
end
|
8
|
+
|
9
|
+
def tag_names
|
10
|
+
self.tag_names = tags.pluck(:name) if super.nil?
|
11
|
+
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
def tag_names=(names)
|
16
|
+
Gutentag.dirtier.call self, names if Gutentag.dirtier
|
17
|
+
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def persist_tags
|
24
|
+
Gutentag::Persistence.new(Gutentag::ChangeState.new(self)).persist
|
25
|
+
end
|
26
|
+
end
|
data/lib/gutentag/dirty.rb
CHANGED
@@ -11,7 +11,10 @@ class Gutentag::Dirty
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def call
|
14
|
-
|
14
|
+
return unless changes.present?
|
15
|
+
|
16
|
+
instance.tag_names_will_change!
|
17
|
+
instance.changed_attributes[:tag_names] = existing
|
15
18
|
end
|
16
19
|
|
17
20
|
private
|
data/lib/gutentag/persistence.rb
CHANGED
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
RSpec.describe "Dirty state of tag names" do
|
6
|
+
let(:article) { Article.create! }
|
7
|
+
|
8
|
+
it "knows what tag names will change" do
|
9
|
+
article.tag_names = ["pancakes"]
|
10
|
+
|
11
|
+
expect(article).to be_changed
|
12
|
+
expect(article.tag_names_changed?).to eq(true)
|
13
|
+
expect(article.tag_names_was).to eq([])
|
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
|
26
|
+
end
|
27
|
+
|
28
|
+
it "knows what tag names have changed" do
|
29
|
+
article.tag_names = ["pancakes"]
|
30
|
+
article.save
|
31
|
+
|
32
|
+
expect(article.tag_names).to eq(["pancakes"])
|
33
|
+
|
34
|
+
expect(article).to_not be_changed
|
35
|
+
expect(article.tag_names_changed?).to eq(false)
|
36
|
+
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
|
51
|
+
end
|
52
|
+
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require "spec_helper"
|
4
4
|
|
5
5
|
describe "Managing tags via names" do
|
6
|
-
let(:article)
|
6
|
+
let(:article) { Article.create }
|
7
7
|
|
8
8
|
it "returns tag names" do
|
9
9
|
melbourne = Gutentag::Tag.create :name => "melbourne"
|
@@ -20,25 +20,6 @@ describe "Managing tags via names" do
|
|
20
20
|
expect(article.tags.collect(&:name)).to eq(["melbourne"])
|
21
21
|
end
|
22
22
|
|
23
|
-
it "makes model dirty when changing through tag_names" do
|
24
|
-
article.tag_names << "melbourne"
|
25
|
-
article.save!
|
26
|
-
|
27
|
-
article.tag_names = ["sydney"]
|
28
|
-
|
29
|
-
expect(article.changed_attributes.stringify_keys).
|
30
|
-
to eq("tag_names" => ["melbourne"])
|
31
|
-
end if Gutentag.dirtier
|
32
|
-
|
33
|
-
it "does not make model dirty when changing through tag_names" do
|
34
|
-
article.tag_names << "melbourne"
|
35
|
-
article.save!
|
36
|
-
|
37
|
-
article.tag_names = ["melbourne"]
|
38
|
-
|
39
|
-
expect(article.changed_attributes).to eq({})
|
40
|
-
end
|
41
|
-
|
42
23
|
it "allows for different tag normalisation" do
|
43
24
|
Gutentag.normaliser = lambda { |name| name.upcase }
|
44
25
|
|
data/spec/spec_helper.rb
CHANGED
@@ -11,8 +11,19 @@ require "rspec/rails"
|
|
11
11
|
|
12
12
|
RSpec.configure do |config|
|
13
13
|
if config.respond_to?(:use_transactional_tests)
|
14
|
-
config.use_transactional_tests =
|
14
|
+
config.use_transactional_tests = false
|
15
15
|
else
|
16
|
-
config.use_transactional_fixtures =
|
16
|
+
config.use_transactional_fixtures = false
|
17
|
+
end
|
18
|
+
|
19
|
+
config.before(:suite) do
|
20
|
+
DatabaseCleaner.strategy = :truncation
|
21
|
+
DatabaseCleaner.clean_with(:truncation)
|
22
|
+
end
|
23
|
+
|
24
|
+
config.around(:each) do |example|
|
25
|
+
DatabaseCleaner.cleaning do
|
26
|
+
example.run
|
27
|
+
end
|
17
28
|
end
|
18
29
|
end
|
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.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pat Allan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-03-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - '='
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 0.8.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: database_cleaner
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.6'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.6'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: rails
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -133,7 +147,8 @@ files:
|
|
133
147
|
- lib/gutentag.rb
|
134
148
|
- lib/gutentag/active_record.rb
|
135
149
|
- lib/gutentag/active_record/class_methods.rb
|
136
|
-
- lib/gutentag/active_record/
|
150
|
+
- lib/gutentag/active_record/legacy_instance_methods.rb
|
151
|
+
- lib/gutentag/active_record/modern_instance_methods.rb
|
137
152
|
- lib/gutentag/change_state.rb
|
138
153
|
- lib/gutentag/dirty.rb
|
139
154
|
- lib/gutentag/engine.rb
|
@@ -144,6 +159,7 @@ files:
|
|
144
159
|
- lib/gutentag/tagged_with/id_query.rb
|
145
160
|
- lib/gutentag/tagged_with/name_query.rb
|
146
161
|
- lib/gutentag/tagged_with/query.rb
|
162
|
+
- spec/acceptance/dirty_state_spec.rb
|
147
163
|
- spec/acceptance/removing_unused_spec.rb
|
148
164
|
- spec/acceptance/tag_names_spec.rb
|
149
165
|
- spec/acceptance/tags_spec.rb
|
@@ -176,7 +192,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
176
192
|
version: '0'
|
177
193
|
requirements: []
|
178
194
|
rubyforge_project:
|
179
|
-
rubygems_version: 2.7.
|
195
|
+
rubygems_version: 2.7.6
|
180
196
|
signing_key:
|
181
197
|
specification_version: 4
|
182
198
|
summary: Good Tags
|