gutentag 2.4.0 → 2.5.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ab338132cb66484c650c46037b6c5133b4ee72c90e7397fbf045cb909029bc3c
4
- data.tar.gz: 7f4d9166ed7d9ef6a0b44a677f0a182434abcc1ceecfe26ea0ab137714b2c6c3
3
+ metadata.gz: 9b86cbc2c649e92b40be12e9be738e3b57f57cb10241103e02d2aa5ea82a0d0a
4
+ data.tar.gz: 916b5eabf6121b235ca9136ac2eaf0113bde665f532bd21afe5b728825718fee
5
5
  SHA512:
6
- metadata.gz: 57eaa6e0442287f4a07dfb612cbb2c18dda900fe8cf7b274f12eecd299b70355711ff786ab20bf0616716e0ba7b1dc8520458d90a779c3cc715fa78e7842304a
7
- data.tar.gz: 067b316bba0642bfedd777ff8cf7d0d85a08f326fd4959466ca3b831be3496fe9aad93872e16a7c3830f29b2ef8aafba8194628188784aed4d60413951d38c6e
6
+ metadata.gz: 3e3dcd7dcae2889b2ab496966bbb5b57c332f46546cbc7dd8f3e557f710c5ae89cfebe833a25bc6efb73c18fb74b858422943072407b328f59251543a000da4e
7
+ data.tar.gz: e7c60af1366e1afbc647162cbd72618be7884c9dc3bf8f580a8b6ddfa61684c7c1546f2fd9f85f0aadceaa2ac7b1dd22b70332b1061c162c2b3695d1fea111ac
@@ -1,8 +1,12 @@
1
1
  inherit_from:
2
2
  - https://gist.githubusercontent.com/pat/ba3b8ffb1901bfe5439b460943b6b019/raw/.rubocop.yml
3
3
 
4
+ require: rubocop-performance
5
+
4
6
  AllCops:
5
- TargetRubyVersion: 2.2
7
+ TargetRubyVersion: 2.3
8
+ Exclude:
9
+ - gemfiles/*.gemfile
6
10
 
7
11
  Metrics/MethodLength:
8
12
  Exclude:
@@ -17,5 +21,18 @@ Style/MultilineTernaryOperator:
17
21
  Exclude:
18
22
  - db/migrate/*.rb
19
23
 
20
- Style/SafeNavigation:
21
- Enabled: false
24
+ # 0.80
25
+
26
+ Style/HashEachMethods:
27
+ Enabled: true
28
+ Style/HashTransformKeys:
29
+ Enabled: true
30
+ Style/HashTransformValues:
31
+ Enabled: true
32
+
33
+ # 0.81
34
+
35
+ Lint/RaiseException:
36
+ Enabled: true
37
+ Lint/StructNewOverride:
38
+ Enabled: true
@@ -1,16 +1,23 @@
1
1
  language: ruby
2
+ dist: xenial
2
3
  script: bundle exec appraisal rake
3
4
  rvm:
4
- - 2.2.10
5
- - 2.3.7
6
- - 2.4.4
7
- - 2.5.1
8
- - jruby-9.1.16.0
5
+ - 2.3.8
6
+ - 2.4.10
7
+ - 2.5.8
8
+ - 2.6.6
9
+ - 2.7.1
10
+ # - jruby-9.2.8.0
9
11
  before_install:
10
- - gem install bundler
12
+ - gem install bundler --version 1.17.3
13
+ install:
14
+ - bundle _1.17.3_ install --jobs=3 --retry=3
11
15
  before_script:
12
16
  - bundle exec appraisal install
13
17
  env:
14
18
  - DATABASE=postgres
15
19
  - DATABASE=mysql
16
20
  - DATABASE=sqlite
21
+ services:
22
+ - mysql
23
+ - postgresql
data/Appraisals CHANGED
@@ -1,37 +1,43 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- appraise "rails_3_2" do
4
- gem "rails", "~> 3.2.22.5"
5
- gem "mysql2", "~> 0.3.10", :platform => :ruby
6
- end if RUBY_VERSION.to_f <= 2.2
7
-
8
3
  appraise "rails_4_0" do
9
- gem "rails", "~> 4.0.13"
10
- gem "mysql2", "~> 0.3.10", :platform => :ruby
4
+ gem "rails", "~> 4.0.13"
5
+ gem "mysql2", "~> 0.3.10", :platform => :ruby
11
6
  end if RUBY_VERSION.to_f < 2.4
12
7
 
13
8
  appraise "rails_4_1" do
14
- gem "rails", "~> 4.1.16"
15
- gem "mysql2", "~> 0.3.13", :platform => :ruby
9
+ gem "rails", "~> 4.1.16"
10
+ gem "mysql2", "~> 0.3.13", :platform => :ruby
16
11
  end if RUBY_VERSION.to_f < 2.4
17
12
 
18
13
  appraise "rails_4_2" do
19
- gem "rails", "~> 4.2.8"
20
- gem "mysql2", "~> 0.4.0", :platform => :ruby
21
- end
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
22
21
 
23
22
  appraise "rails_5_0" do
24
23
  gem "rails", "~> 5.0.3"
25
24
  gem "mysql2", "~> 0.4.0", :platform => :ruby
26
- end if RUBY_VERSION.to_f >= 2.2 && RUBY_PLATFORM != "java"
25
+ end if RUBY_VERSION.to_f >= 2.2
27
26
 
28
27
  appraise "rails_5_1" do
29
28
  gem "rails", "~> 5.1.1"
30
29
  gem "mysql2", "~> 0.4.0", :platform => :ruby
31
- end if RUBY_VERSION.to_f >= 2.2 && RUBY_PLATFORM != "java"
30
+ end if RUBY_VERSION.to_f >= 2.2
32
31
 
33
32
  appraise "rails_5_2" do
34
33
  gem "rails", "~> 5.2.0"
35
34
  gem "pg", "~> 1.0", :platform => :ruby
36
35
  gem "mysql2", "~> 0.5.0", :platform => :ruby
37
- end if RUBY_VERSION.to_f >= 2.2 && RUBY_PLATFORM != "java"
36
+ end if RUBY_VERSION.to_f >= 2.2
37
+
38
+ appraise "rails_6_0" do
39
+ gem "rails", "~> 6.0.0"
40
+ gem "pg", "~> 1.0", :platform => :ruby
41
+ gem "mysql2", "~> 0.5.0", :platform => :ruby
42
+ gem "sqlite3", "~> 1.4", :platform => :ruby
43
+ end if RUBY_VERSION.to_f >= 2.5 && RUBY_PLATFORM != "java"
@@ -2,6 +2,48 @@
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.5.3 - 2020-06-28
6
+
7
+ ### Fixed
8
+
9
+ * Use `saved_change_to_tag_names?` instead of `tag_names_previously_changed?` for Rails 5.1+ ([Morten Trolle](https://github.com/mtrolle) in [70](https://github.com/pat/gutentag/pull/70)).
10
+ * `Gutentag::Tag.names_for_scope` now handles empty scopes ([Mike Gunderloy](https://github.com/ffmike) in [#73](https://github.com/pat/gutentag/pull/73)).
11
+
12
+ ## 2.5.2 - 2019-07-08
13
+
14
+ ### Fixed
15
+
16
+ * `tag_names` will no longer be referenced as a database column when tagged models are requested in joins in Rails 4.2 (as reported in [issue #67](https://github.com/pat/gutentag/issues/67)).
17
+
18
+ ## 2.5.1 - 2019-05-10
19
+
20
+ ### Fixed
21
+
22
+ * Ensuring consistent behaviour for tag_names array - names are not duplicated, and are normalised prior to saving (as discussed in [issue #66](https://github.com/pat/gutentag/issues/66)).
23
+
24
+ ## 2.5.0 - 2019-03-15
25
+
26
+ **Please note this release ends official support of Rails 3.2 and Ruby (MRI) 2.2.** The code currently still works on Ruby 2.2, and all features except for the new `Gutentag::Tag.names_for_scope` method work in Rails 3.2, but they're no longer tested against, and cannot be guaranteed to work in future releases.
27
+
28
+ ### Added
29
+
30
+ * Added the `Gutentag::Tag.names_for_scope(scope)` method, which accepts an ActiveRecord model or a relation, and returns all tag names associated to that model/relation.
31
+
32
+ ### Changed
33
+
34
+ * Removing support for MRI 2.2 and Rails 3.2.
35
+
36
+ ## 2.4.1 - 2019-02-22
37
+
38
+ ### Changed
39
+
40
+ * Tests are now run against Rails 6.0, MRI 2.6, JRuby 9.2.5.
41
+ * The README documents a simpler migration ([seelensonne](https://github.com/seelensonne) in [#55](https://github.com/pat/gutentag/pull/55)).
42
+
43
+ ### Fixed
44
+
45
+ * Do not record changes when tag_names did not change ([Stephen Oberther](https://github.com/smo921) in [#60](https://github.com/pat/gutentag/pull/60)).
46
+
5
47
  ## 2.4.0 - 2018-05-18
6
48
 
7
49
  ### Changed
data/Gemfile CHANGED
@@ -6,12 +6,12 @@ gemspec
6
6
 
7
7
  gem "test-unit", :platform => :ruby_22
8
8
 
9
- gem "mysql2", "~> 0.3", :platform => :ruby
10
- gem "pg", "~> 0.18", :platform => :ruby
11
- gem "sqlite3", "~> 1.3", :platform => :ruby
9
+ gem "mysql2", "~> 0.3", :platform => :ruby
10
+ gem "pg", "~> 0.18", :platform => :ruby
11
+ gem "sqlite3", "~> 1.3.13", :platform => :ruby
12
12
 
13
- gem "activerecord-jdbcmysql-adapter", "~> 1.3.23", :platform => :jruby
14
- gem "activerecord-jdbcpostgresql-adapter", "~> 1.3.23", :platform => :jruby
15
- gem "activerecord-jdbcsqlite3-adapter", "~> 1.3.23", :platform => :jruby
13
+ gem "activerecord-jdbcmysql-adapter", ">= 1.3.23", :platform => :jruby
14
+ gem "activerecord-jdbcpostgresql-adapter", ">= 1.3.23", :platform => :jruby
15
+ gem "activerecord-jdbcsqlite3-adapter", ">= 1.3.23", :platform => :jruby
16
16
 
17
- gem "activerecord", [">= 3.2.22", "< 5"] if RUBY_PLATFORM == "java"
17
+ gem "activerecord", [">= 3.2.22"] if RUBY_PLATFORM == "java"
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Gutentag
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/gutentag.png)](http://badge.fury.io/rb/gutentag)
4
- [![Build Status](https://travis-ci.org/pat/gutentag.png?branch=master)](https://travis-ci.org/pat/gutentag)
5
- [![Code Climate](https://codeclimate.com/github/pat/gutentag.png)](https://codeclimate.com/github/pat/gutentag)
3
+ [![Gem Version](https://badge.fury.io/rb/gutentag.svg)](http://badge.fury.io/rb/gutentag)
4
+ [![Build Status](https://travis-ci.org/pat/gutentag.svg?branch=master)](https://travis-ci.org/pat/gutentag)
5
+ [![Code Climate](https://codeclimate.com/github/pat/gutentag.svg)](https://codeclimate.com/github/pat/gutentag)
6
6
 
7
7
  A good, simple, solid tagging extension for ActiveRecord.
8
8
 
@@ -16,6 +16,7 @@ If you want to know more, read [this blog post](http://freelancing-gods.com/post
16
16
  * [Installation](#installation)
17
17
  * [Upgrading](#upgrading)
18
18
  * [Configuration](#configuration)
19
+ * [Extending](#extending)
19
20
  * [Contribution](#contribution)
20
21
  * [Licence](#licence)
21
22
 
@@ -72,15 +73,17 @@ Article.tagged_with(:ids => [tag_a.id, tag_b.id], :match => :all)
72
73
 
73
74
  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.
74
75
 
75
- * Ruby: MRI v2.2-v2.5, JRuby v9.1
76
- * Rails/ActiveRecord: v3.2-v5.2
76
+ * Ruby: MRI v2.3-v2.6, JRuby v9.2.5
77
+ * Rails/ActiveRecord: v4.0-v6.0
78
+
79
+ 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.
77
80
 
78
81
  ### Installing
79
82
 
80
83
  Get it into your Gemfile - and don't forget the version constraint!
81
84
 
82
85
  ```Ruby
83
- gem 'gutentag', '~> 2.4'
86
+ gem 'gutentag', '~> 2.5'
84
87
  ```
85
88
 
86
89
  Next: your tags get persisted to your database, so let's import and run the migrations to get the tables set up:
@@ -90,31 +93,25 @@ rake gutentag:install:migrations
90
93
  rake db:migrate
91
94
  ```
92
95
 
96
+ If you're using UUID primary keys, make sure you alter the migration files before running `db:migrate` to use UUIDs for the `taggable_id` foreign key column (as noted in [issue 57](https://github.com/pat/gutentag/issues/57).)
97
+
93
98
  ### Without Rails
94
99
 
95
100
  If you want to use Gutentag outside of Rails, you can. However, there is one caveat: You'll want to set up your database with the same schema (as importing in the migrations isn't possible without Rails). The schema from 0.7.0 onwards is below:
96
101
 
97
- ```Ruby
98
- create_table :gutentag_taggings do |t|
99
- t.integer :tag_id, null: false
100
- t.integer :taggable_id, null: false
101
- t.string :taggable_type, null: false
102
- t.timestamps null: false
103
- end
104
-
105
- add_index :gutentag_taggings, :tag_id
106
- add_index :gutentag_taggings, [:taggable_type, :taggable_id]
107
- add_index :gutentag_taggings, [:taggable_type, :taggable_id, :tag_id],
108
- unique: true, name: 'unique_taggings'
109
-
102
+ ```ruby
110
103
  create_table :gutentag_tags do |t|
111
- t.string :name, null: false
112
- t.integer :taggings_count, null: false, default: 0
113
- t.timestamps null: false
104
+ t.string :name, null: false, index: {unique: true}
105
+ t.bigint :taggings_count, null: false, index: true, default: 0
106
+ t.timestamps null: false
114
107
  end
115
108
 
116
- add_index :gutentag_tags, :name, unique: true
117
- add_index :gutentag_tags, :taggings_count
109
+ create_table :gutentag_taggings do |t|
110
+ t.references :tag, null: false, index: true, foreign_key: {to_table: :gutentag_tags}
111
+ t.references :taggable, null: false, index: true, polymorphic: true
112
+ t.timestamps null: false
113
+ end
114
+ add_index :gutentag_taggings, [:taggable_type, :taggable_id, :tag_id], unique: true, name: "gutentag_taggings_uniqueness"
118
115
  ```
119
116
 
120
117
  <h2 id="upgrading">Upgrading</h2>
@@ -155,6 +152,19 @@ Gutentag.normaliser = lambda { |value| value.to_s.upcase }
155
152
 
156
153
  Gutentag ignores case by default, but can be customised to be case-sensitive by supplying your own validations and normaliser, as outlined by [Robin Mehner](https://github.com/rmehner) in [issue 42](https://github.com/pat/gutentag/issues/42). Further changes may be required for your schema though, depending on your database.
157
154
 
155
+ <h2 id="extending">Extending</h2>
156
+
157
+ If you need to extend Gutentag's models, you will need to wrap the `include` inside a `to_prepare` hook to ensure it's loaded consistently in all Rails environments:
158
+
159
+ ```ruby
160
+ # config/initializers/gutentag.rb or equivalent
161
+ Rails.application.config.to_prepare do
162
+ Gutentag::Tag.include TagExtensions
163
+ end
164
+ ```
165
+
166
+ Further discussion and examples of this can be found in [issue 65](https://github.com/pat/gutentag/issues/65).
167
+
158
168
  <h2 id="contribution">Contribution</h2>
159
169
 
160
170
  Please note that this project now has a [Contributor Code of Conduct](http://contributor-covenant.org/version/1/0/0/). By participating in this project you agree to abide by its terms.
@@ -19,6 +19,19 @@ class Gutentag::Tag < ActiveRecord::Base
19
19
  find_by_name(name) || create(:name => name)
20
20
  end
21
21
 
22
+ def self.names_for_scope(scope)
23
+ join_conditions = {:taggable_type => scope.name}
24
+ if scope.is_a?(ActiveRecord::Relation)
25
+ return Gutentag::Tag.none unless scope.current_scope.present?
26
+
27
+ join_conditions[:taggable_id] = scope.select(:id)
28
+ end
29
+
30
+ joins(:taggings).where(
31
+ Gutentag::Tagging.table_name => join_conditions
32
+ ).distinct.pluck(:name)
33
+ end
34
+
22
35
  def name=(value)
23
36
  super(Gutentag.normaliser.call(value))
24
37
  end
@@ -1,9 +1,8 @@
1
1
  # frozen_string_literal: true
2
- # -*- encoding: utf-8 -*-
3
2
 
4
3
  Gem::Specification.new do |s|
5
4
  s.name = "gutentag"
6
- s.version = "2.4.0"
5
+ s.version = "2.5.3"
7
6
  s.authors = ["Pat Allan"]
8
7
  s.email = ["pat@freelancing-gods.com"]
9
8
  s.homepage = "https://github.com/pat/gutentag"
@@ -17,11 +16,12 @@ Gem::Specification.new do |s|
17
16
 
18
17
  s.add_runtime_dependency "activerecord", ">= 3.2.0"
19
18
 
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"
19
+ s.add_development_dependency "appraisal", "~> 2.1.0"
20
+ s.add_development_dependency "bundler", ">= 1.17"
21
+ s.add_development_dependency "combustion", "~> 1.1"
22
+ s.add_development_dependency "database_cleaner", "~> 1.6"
24
23
  s.add_development_dependency "rails"
25
- s.add_development_dependency "rspec-rails", "~> 3.1"
26
- s.add_development_dependency "rubocop", "~> 0.52.1"
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"
27
27
  end
@@ -31,7 +31,7 @@ class Gutentag::ActiveRecord
31
31
  end
32
32
 
33
33
  def add_attribute
34
- if legacy?
34
+ if ActiveRecord::VERSION::STRING.to_f <= 4.2
35
35
  model.define_attribute_method "tag_names"
36
36
  else
37
37
  model.attribute "tag_names", ActiveRecord::Type::Value.new,
@@ -2,6 +2,8 @@
2
2
 
3
3
  # For Rails 5.0+
4
4
  module Gutentag::ActiveRecord::InstanceMethods
5
+ AR_VERSION = ActiveRecord::VERSION::STRING.to_f
6
+
5
7
  # If the tag_names attribute was one of the modified values, then let's just
6
8
  # use the modifications, rather than overwriting the stored value.
7
9
  #
@@ -9,7 +11,12 @@ module Gutentag::ActiveRecord::InstanceMethods
9
11
  # the instance directly (e.g. article.tags << tag), which invokes the save
10
12
  # callbacks, but the old tag_names value is stored but not updated.
11
13
  def reset_tag_names
12
- return if tag_names_previously_changed?
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?
13
20
 
14
21
  # Update the underlying value rather than going through the setter, to
15
22
  # ensure this update doesn't get marked as a 'change'.
@@ -28,7 +35,7 @@ module Gutentag::ActiveRecord::InstanceMethods
28
35
  def tag_names=(names)
29
36
  # This value is about to be overwritten, but we want to make sure the change
30
37
  # tracking doesn't think the original value was nil.
31
- @attributes.write_from_database "tag_names", []
38
+ @attributes.write_from_database "tag_names", tags.pluck(:name)
32
39
 
33
40
  super Gutentag::TagNames.call(names)
34
41
  end
@@ -16,7 +16,7 @@ module Gutentag::ActiveRecord::InstanceMethods
16
16
  def tag_names=(names)
17
17
  names = Gutentag::TagNames.call(names)
18
18
 
19
- Gutentag.dirtier.call self, names if Gutentag.dirtier
19
+ Gutentag.dirtier.call self, names if Gutentag.dirtier.present?
20
20
 
21
21
  @tag_names = names
22
22
  end
@@ -8,22 +8,25 @@ module Gutentag::ActiveRecord::InstanceMethods
8
8
  def reset_tag_names
9
9
  # Update the underlying value rather than going through the setter, to
10
10
  # ensure this update doesn't get marked as a 'change'.
11
- self.tag_names = nil
11
+ @tag_names = nil
12
12
  end
13
13
 
14
14
  def tag_names
15
- # If the underlying value is nil, we've not requested this from the
16
- # database yet.
17
- if read_attribute("tag_names") { nil }.nil?
18
- self.tag_names = tags.pluck(:name)
15
+ @tag_names ||= begin
16
+ raw = tags.pluck(:name)
17
+ raw_write_attribute "tag_names", raw
18
+ raw
19
19
  end
20
-
21
- # Use ActiveRecord's underlying implementation with change tracking.
22
- super
23
20
  end
24
21
 
25
22
  def tag_names=(names)
26
- super Gutentag::TagNames.call(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
27
30
  end
28
31
 
29
32
  private
@@ -4,6 +4,8 @@ class Gutentag::TagNames
4
4
  def self.call(names)
5
5
  return nil if names.nil?
6
6
 
7
- names.reject(&:blank?)
7
+ names.reject(&:blank?).uniq.collect do |name|
8
+ Gutentag.normaliser.call(name)
9
+ end
8
10
  end
9
11
  end
@@ -36,7 +36,7 @@ class Gutentag::TagValidations
36
36
 
37
37
  def add_length_validation?
38
38
  klass.table_exists? && limit.present?
39
- rescue *DATABASE_ERROR_CLASSES
39
+ rescue *DATABASE_ERROR_CLASSES => _error
40
40
  warn <<-MESSAGE
41
41
  The database is not currently available, and so Gutentag was not able to set
42
42
  up tag validations completely (in particular: adding a length limit to match
@@ -27,7 +27,7 @@ RSpec.describe "Dirty state of tag names" do
27
27
 
28
28
  it "knows what tag names have changed" do
29
29
  article.tag_names = ["pancakes"]
30
- article.save
30
+ article.save!
31
31
 
32
32
  expect(article.tag_names).to eq(["pancakes"])
33
33
 
@@ -49,4 +49,12 @@ RSpec.describe "Dirty state of tag names" do
49
49
  expect(article.tag_names_in_database).to eq(["pancakes"])
50
50
  end
51
51
  end
52
+
53
+ it "knows when tags have not changed" do
54
+ article.tag_names = ["pancakes"]
55
+ article.save!
56
+
57
+ article.tag_names = ["pancakes"]
58
+ expect(article.changes).to eq({})
59
+ end
52
60
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- describe "Removing unused" do
5
+ RSpec.describe "Removing unused" do
6
6
  let(:article) { Article.create }
7
7
 
8
8
  it "deletes only unused tags" do
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe "Tag names for scopes" do
6
+ it "returns tag names for a given model" do
7
+ Article.create :tag_names => %w[ koala wombat ]
8
+ Article.create :tag_names => %w[ cassowary ]
9
+
10
+ expect(Gutentag::Tag.names_for_scope(Article)).
11
+ to match_array(%w[ koala wombat cassowary ])
12
+ end
13
+
14
+ it "returns tag names for a given scope" do
15
+ Article.create :title => "mammals", :tag_names => %w[ koala wombat ]
16
+ Article.create :title => "birds", :tag_names => %w[ cassowary ]
17
+
18
+ expect(Gutentag::Tag.names_for_scope(Article.where(:title => "mammals"))).
19
+ to match_array(%w[ koala wombat ])
20
+ end
21
+
22
+ it "does not duplicate tag names for a given model/scope" do
23
+ Article.create :tag_names => %w[ koala wombat ]
24
+ Article.create :tag_names => %w[ cassowary ]
25
+ Article.create :tag_names => %w[ cassowary wombat ]
26
+
27
+ expect(Gutentag::Tag.names_for_scope(Article)).
28
+ to match_array(%w[ koala wombat cassowary ])
29
+ end
30
+
31
+ it "returns an empty array for an empty scope" do
32
+ Article.create :title => "mammals", :tag_names => %w[ koala wombat ]
33
+ Article.create :title => "birds", :tag_names => %w[ cassowary ]
34
+
35
+ expect(Gutentag::Tag.names_for_scope(Article.where(:title => "reptiles"))).
36
+ to match_array([])
37
+ end
38
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- describe "Managing tags via names" do
5
+ RSpec.describe "Managing tags via names" do
6
6
  let(:article) { Article.create }
7
7
 
8
8
  it "returns tag names" do
@@ -70,6 +70,13 @@ describe "Managing tags via names" do
70
70
  expect(article.tags.collect(&:name)).to eq(%w[ portland oregon ruby ])
71
71
  end
72
72
 
73
+ it "does not repeat appended names that exist in the array of strings" do
74
+ article.tag_names = %w[ portland oregon ]
75
+ article.tag_names += %w[ oregon ruby ]
76
+
77
+ expect(article.tag_names).to match(%w[ portland oregon ruby ])
78
+ end
79
+
73
80
  it "removes a single tag name" do
74
81
  article.tag_names = %w[ portland oregon ]
75
82
  article.tag_names.delete "oregon"
@@ -99,6 +106,11 @@ describe "Managing tags via names" do
99
106
  expect(article.tags.collect(&:name)).to eq(%w[ portland ])
100
107
  end
101
108
 
109
+ it "normalises tag names" do
110
+ article.tag_names = %w[ Perth ]
111
+ expect(article.tag_names).to eq(%w[ perth ])
112
+ end
113
+
102
114
  it "allows setting of tag names on unpersisted objects" do
103
115
  article = Article.new :tag_names => %w[ melbourne pancakes ]
104
116
  article.save!
@@ -123,4 +135,8 @@ describe "Managing tags via names" do
123
135
 
124
136
  expect(article.tag_names).to eq(%w[ melbourne ])
125
137
  end
138
+
139
+ it "allows eager-loading of the model via an association" do
140
+ expect { Comment.eager_load(:article).to_a }.to_not raise_error
141
+ end
126
142
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- describe "Adding and removing tags" do
5
+ RSpec.describe "Adding and removing tags" do
6
6
  let(:article) { Article.create }
7
7
  let(:pancakes) { Gutentag::Tag.create :name => "pancakes" }
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- describe Gutentag::ActiveRecord do
5
+ RSpec.describe Gutentag::ActiveRecord do
6
6
  describe ".tagged_with" do
7
7
  let!(:melbourne_article) do
8
8
  article = Article.create :title => "Overview"
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- describe Gutentag do
5
+ RSpec.describe Gutentag do
6
6
  describe ".normalizer" do
7
7
  it "downcases the provided name" do
8
8
  expect(Gutentag.normaliser.call("Tasty Pancakes")).to eq("tasty pancakes")
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Comment < ActiveRecord::Base
4
+ belongs_to :article
5
+ end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Thinkpiece < Article
4
- #
5
4
  end
@@ -6,4 +6,10 @@ ActiveRecord::Schema.define do
6
6
  t.string :type
7
7
  t.timestamps :null => false
8
8
  end
9
+
10
+ create_table :comments, :force => true do |t|
11
+ t.references :article
12
+ t.string :name
13
+ t.text :text
14
+ end
9
15
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- describe Gutentag::Tag, :type => :model do
5
+ RSpec.describe Gutentag::Tag, :type => :model do
6
6
  describe ".find_by_name" do
7
7
  it "returns a tag with the same name" do
8
8
  existing = Gutentag::Tag.create! :name => "pancakes"
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- describe Gutentag::Tagging, :type => :model do
5
+ RSpec.describe Gutentag::Tagging, :type => :model do
6
6
  describe "#valid?" do
7
7
  let(:tag) { Gutentag::Tag.create! :name => "pancakes" }
8
8
  let(:taggable) { Article.create! }
@@ -4,12 +4,16 @@ require "bundler/setup"
4
4
 
5
5
  Bundler.require :default, :development
6
6
 
7
+ Dir["#{__dir__}/support/**/*.rb"].sort.each { |file| require file }
8
+
7
9
  Combustion.initialize! :active_record
8
10
  ActiveSupport.run_load_hooks :gutentag unless defined?(Gutentag::Engine)
9
11
 
10
12
  require "rspec/rails"
11
13
 
12
14
  RSpec.configure do |config|
15
+ config.disable_monkey_patching!
16
+
13
17
  if config.respond_to?(:use_transactional_tests)
14
18
  config.use_transactional_tests = false
15
19
  else
@@ -0,0 +1,27 @@
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
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.0
4
+ version: 2.5.3
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-05-18 00:00:00.000000000 Z
11
+ date: 2020-06-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -44,28 +44,28 @@ dependencies:
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 1.7.12
47
+ version: '1.17'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: 1.7.12
54
+ version: '1.17'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: combustion
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '='
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.8.0
61
+ version: '1.1'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '='
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 0.8.0
68
+ version: '1.1'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: database_cleaner
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -114,14 +114,28 @@ dependencies:
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: 0.52.1
117
+ version: 0.81.0
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 0.81.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: rubocop-performance
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1'
118
132
  type: :development
119
133
  prerelease: false
120
134
  version_requirements: !ruby/object:Gem::Requirement
121
135
  requirements:
122
136
  - - "~>"
123
137
  - !ruby/object:Gem::Version
124
- version: 0.52.1
138
+ version: '1'
125
139
  description: A good, simple, solid tagging extension for ActiveRecord
126
140
  email:
127
141
  - pat@freelancing-gods.com
@@ -163,11 +177,13 @@ files:
163
177
  - lib/gutentag/tagged_with/query.rb
164
178
  - spec/acceptance/dirty_state_spec.rb
165
179
  - spec/acceptance/removing_unused_spec.rb
180
+ - spec/acceptance/tag_names_for_scope_spec.rb
166
181
  - spec/acceptance/tag_names_spec.rb
167
182
  - spec/acceptance/tags_spec.rb
168
183
  - spec/gutentag/active_record_spec.rb
169
184
  - spec/gutentag_spec.rb
170
185
  - spec/internal/app/models/article.rb
186
+ - spec/internal/app/models/comment.rb
171
187
  - spec/internal/app/models/thinkpiece.rb
172
188
  - spec/internal/config/database.yml
173
189
  - spec/internal/db/schema.rb
@@ -175,6 +191,7 @@ files:
175
191
  - spec/models/gutentag/tag_spec.rb
176
192
  - spec/models/gutentag/tagging_spec.rb
177
193
  - spec/spec_helper.rb
194
+ - spec/support/mysql.rb
178
195
  homepage: https://github.com/pat/gutentag
179
196
  licenses:
180
197
  - MIT
@@ -194,8 +211,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
194
211
  - !ruby/object:Gem::Version
195
212
  version: '0'
196
213
  requirements: []
197
- rubyforge_project:
198
- rubygems_version: 2.7.6
214
+ rubygems_version: 3.1.2
199
215
  signing_key:
200
216
  specification_version: 4
201
217
  summary: Good Tags