acts-as-taggable-on 3.2.1 → 3.2.2
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/CHANGELOG.md +27 -15
- data/README.md +17 -10
- data/acts-as-taggable-on.gemspec +7 -7
- data/lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb +1 -0
- data/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb +23 -23
- data/lib/acts_as_taggable_on/acts_as_taggable_on/related.rb +5 -5
- data/lib/acts_as_taggable_on/tag_list.rb +2 -1
- data/lib/acts_as_taggable_on/taggable.rb +0 -2
- data/lib/acts_as_taggable_on/utils.rb +44 -44
- data/lib/acts_as_taggable_on/version.rb +1 -1
- data/spec/acts_as_taggable_on/tag_spec.rb +7 -5
- data/spec/acts_as_taggable_on/taggable_spec.rb +25 -24
- data/spec/acts_as_taggable_on/utils_spec.rb +5 -11
- data/spec/internal/db/schema.rb +1 -1
- data/spec/support/database_cleaner.rb +4 -0
- metadata +28 -30
- data/spec/bm.rb +0 -52
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc40e6d7c5c8b741bfc71aee7ae2406c6f824108
|
4
|
+
data.tar.gz: 3c89e20ed3b39ef33d52724d4bb8b9aa3e5738f9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e4142af492646d113a10fa0ae4815d91a281f2a55d60fb70b653a96d4ac58e24c56e1e10bcbf9907bbcc06cee2b476b6ec4a568cc25e5247578a140cbf388d85
|
7
|
+
data.tar.gz: eceb8e025f83cdbc9e237405eac982aa3b7c7ef0f54d803fcd80d1ed837b833d4f07fe549f0eb0eaa443edb5cdc84bcad79555a67a886e7fc706b46aa5d37b35
|
data/CHANGELOG.md
CHANGED
@@ -4,21 +4,33 @@ Each change should fall into categories that would affect whether the release is
|
|
4
4
|
|
5
5
|
As such, a _Feature_ would map to either major or minor. A _bug fix_ to a patch. And _misc_ is either minor or patch, the difference being kind of fuzzy for the purposes of history. Adding tests would be patch level.
|
6
6
|
|
7
|
-
### Master [changes](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.
|
8
|
-
|
9
|
-
* Breaking Changes
|
10
|
-
*
|
11
|
-
*
|
12
|
-
* Fixes
|
13
|
-
*
|
14
|
-
*
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
*
|
21
|
-
|
7
|
+
### Master [changes](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.2.0...master)
|
8
|
+
|
9
|
+
* Breaking Changes
|
10
|
+
* Taggable models are not extend with ActsAsTaggableOn::Utils anymore
|
11
|
+
* Features
|
12
|
+
* Fixes
|
13
|
+
* Performance
|
14
|
+
* Misc
|
15
|
+
* Deleted outdated benchmark script
|
16
|
+
|
17
|
+
|
18
|
+
### [3.2.0 / 2014-05-1](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.1.1...v3.2.0)
|
19
|
+
|
20
|
+
* Breaking Changes
|
21
|
+
* ActsAsTaggableOn::Tag is not extend with ActsAsTaggableOn::Utils anymore
|
22
|
+
* Features
|
23
|
+
* [@chess #413 Hook to support STI subclasses of Tag in save_tags](https://github.com/mbleigh/acts-as-taggable-on/pull/413)
|
24
|
+
* Fixes
|
25
|
+
* [@jdelStrother #515 Rename Compatibility methods to reduce chance of conflicts ](https://github.com/mbleigh/acts-as-taggable-on/pull/515)
|
26
|
+
* [@seuros #512 fix for << method](https://github.com/mbleigh/acts-as-taggable-on/pull/512)
|
27
|
+
* [@sonots #510 fix IN subquery error for mysql](https://github.com/mbleigh/acts-as-taggable-on/pull/510)
|
28
|
+
* [@jonseaberg #499 fix for race condition when multiple processes try to add the same tag](https://github.com/mbleigh/acts-as-taggable-on/pull/499)
|
29
|
+
* [@leklund #496 Fix for distinct and postgresql json columns errors](https://github.com/mbleigh/acts-as-taggable-on/pull/496)
|
30
|
+
* [@thatbettina & @plexus #394 Multiple quoted tags](https://github.com/mbleigh/acts-as-taggable-on/pull/496)
|
31
|
+
* Performance
|
32
|
+
* Misc
|
33
|
+
* [@seuros #511 Rspec 3](https://github.com/mbleigh/acts-as-taggable-on/pull/511)
|
22
34
|
|
23
35
|
### [3.1.0 / 2014-03-31](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.0.1...v3.1.0)
|
24
36
|
|
data/README.md
CHANGED
@@ -135,11 +135,13 @@ these methods are added to the model: `skill_list`(and `skill_list.add`, `skill_
|
|
135
135
|
# => ["joking", "clowning", "boxing", "coding"]
|
136
136
|
|
137
137
|
@another_user = User.new(:name => "Alice")
|
138
|
-
@
|
139
|
-
@
|
138
|
+
@another_user.skill_list.add("clowning")
|
139
|
+
@another_user.save
|
140
140
|
|
141
141
|
User.skill_counts
|
142
|
-
=> [#<ActsAsTaggableOn::Tag id: 1, name: "joking", taggings_count:
|
142
|
+
=> [#<ActsAsTaggableOn::Tag id: 1, name: "joking", taggings_count: 1>,
|
143
|
+
#<ActsAsTaggableOn::Tag id: 2, name: "clowning", taggings_count: 2>,
|
144
|
+
#<ActsAsTaggableOn::Tag id: 3, name: "boxing", taggings_count: 1>]
|
143
145
|
```
|
144
146
|
|
145
147
|
To preserve the order in which tags are created use `acts_as_ordered_taggable`:
|
@@ -176,22 +178,22 @@ end
|
|
176
178
|
User.tagged_with("awesome").by_join_date
|
177
179
|
User.tagged_with("awesome").by_join_date.paginate(:page => params[:page], :per_page => 20)
|
178
180
|
|
179
|
-
# Find
|
181
|
+
# Find users that matches all given tags:
|
180
182
|
User.tagged_with(["awesome", "cool"], :match_all => true)
|
181
183
|
|
182
|
-
# Find
|
184
|
+
# Find users with any of the specified tags:
|
183
185
|
User.tagged_with(["awesome", "cool"], :any => true)
|
184
186
|
|
185
|
-
# Find
|
187
|
+
# Find users that has not been tagged with awesome or cool:
|
186
188
|
User.tagged_with(["awesome", "cool"], :exclude => true)
|
187
189
|
|
188
|
-
# Find
|
190
|
+
# Find users with any of the tags based on context:
|
189
191
|
User.tagged_with(['awesome', 'cool'], :on => :tags, :any => true).tagged_with(['smart', 'shy'], :on => :skills, :any => true)
|
190
192
|
```
|
191
193
|
|
192
|
-
You can also use `:wild => true` option along with `:any` or `:exclude` option. It will looking for `%awesome%` and `%cool%` in
|
194
|
+
You can also use `:wild => true` option along with `:any` or `:exclude` option. It will be looking for `%awesome%` and `%cool%` in SQL.
|
193
195
|
|
194
|
-
__Tip:__ `User.tagged_with([])` or `User.tagged_with('')` will return `[]`,
|
196
|
+
__Tip:__ `User.tagged_with([])` or `User.tagged_with('')` will return `[]`, an empty set of records.
|
195
197
|
|
196
198
|
### Relationships
|
197
199
|
|
@@ -273,7 +275,7 @@ Photo.tagged_with("paris", :on => :locations, :owned_by => @some_user)
|
|
273
275
|
To construct tag clouds, the frequency of each tag needs to be calculated.
|
274
276
|
Because we specified `acts_as_taggable_on` on the `User` class, we can
|
275
277
|
get a calculation of all the tag counts by using `User.tag_counts_on(:customs)`. But what if we wanted a tag count for
|
276
|
-
|
278
|
+
a single user's posts? To achieve this we call tag_counts on the association:
|
277
279
|
|
278
280
|
```ruby
|
279
281
|
User.find(:first).posts.tag_counts_on(:tags)
|
@@ -360,6 +362,11 @@ We have a long list of valued contributors. [Check them all](https://github.com/
|
|
360
362
|
|
361
363
|
* [Joost Baaij](https://github.com/tilsammans)
|
362
364
|
|
365
|
+
## TODO
|
366
|
+
|
367
|
+
- Write benchmark script
|
368
|
+
- Resolve concurrency issues
|
369
|
+
|
363
370
|
## Testing
|
364
371
|
|
365
372
|
Acts As Taggable On uses RSpec for its test coverage. Inside the gem
|
data/acts-as-taggable-on.gemspec
CHANGED
@@ -26,13 +26,13 @@ Gem::Specification.new do |gem|
|
|
26
26
|
gem.add_runtime_dependency 'actionpack', ['>= 3', '< 5']
|
27
27
|
|
28
28
|
gem.add_development_dependency 'sqlite3'
|
29
|
-
gem.add_development_dependency 'mysql2'
|
29
|
+
gem.add_development_dependency 'mysql2'
|
30
30
|
gem.add_development_dependency 'pg'
|
31
31
|
|
32
|
-
gem.add_development_dependency 'rspec-rails' , '~> 3.0.0.
|
33
|
-
gem.add_development_dependency 'rspec-its'
|
34
|
-
gem.add_development_dependency 'rspec'
|
35
|
-
gem.add_development_dependency 'ammeter'
|
36
|
-
gem.add_development_dependency 'barrier'
|
37
|
-
gem.add_development_dependency 'database_cleaner'
|
32
|
+
gem.add_development_dependency 'rspec-rails' , '~> 3.0.0.beta2'
|
33
|
+
gem.add_development_dependency 'rspec-its', '~> 1.0'
|
34
|
+
gem.add_development_dependency 'rspec', '3.0.0.beta2'
|
35
|
+
gem.add_development_dependency 'ammeter', '~> 1.0'
|
36
|
+
gem.add_development_dependency 'barrier', '~> 1.0'
|
37
|
+
gem.add_development_dependency 'database_cleaner', '~> 1.2'
|
38
38
|
end
|
@@ -31,6 +31,7 @@ module ActsAsTaggableOn::Taggable
|
|
31
31
|
# to mimic the underlying behavior. While processing this first
|
32
32
|
# call to columns, we do the caching column check and dynamically add
|
33
33
|
# the class and instance methods
|
34
|
+
# FIXME: this method cannot compile in rubinius
|
34
35
|
def columns
|
35
36
|
@acts_as_taggable_on_cache_columns ||= begin
|
36
37
|
db_columns = super
|
@@ -24,16 +24,16 @@ module ActsAsTaggableOn::Taggable
|
|
24
24
|
# when preserving tag order, include order option so that for a 'tags' context
|
25
25
|
# the associations tag_taggings & tags are always returned in created order
|
26
26
|
has_many_with_taggable_compatibility context_taggings, as: :taggable,
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
27
|
+
dependent: :destroy,
|
28
|
+
class_name: 'ActsAsTaggableOn::Tagging',
|
29
|
+
order: taggings_order,
|
30
|
+
conditions: ["#{ActsAsTaggableOn::Tagging.table_name}.context = (?)", tags_type],
|
31
|
+
include: :tag
|
32
32
|
|
33
33
|
has_many_with_taggable_compatibility context_tags, through: context_taggings,
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
source: :tag,
|
35
|
+
class_name: 'ActsAsTaggableOn::Tag',
|
36
|
+
order: taggings_order
|
37
37
|
|
38
38
|
end
|
39
39
|
|
@@ -130,7 +130,7 @@ module ActsAsTaggableOn::Taggable
|
|
130
130
|
taggings_context = context ? "_#{context}" : ''
|
131
131
|
|
132
132
|
taggings_alias = adjust_taggings_alias(
|
133
|
-
"#{alias_base_name[0..4]}#{taggings_context[0..6]}_taggings_#{sha_prefix(tags.map(&:name).join('_'))}"
|
133
|
+
"#{alias_base_name[0..4]}#{taggings_context[0..6]}_taggings_#{ActsAsTaggableOn::Utils.sha_prefix(tags.map(&:name).join('_'))}"
|
134
134
|
)
|
135
135
|
|
136
136
|
tagging_join = "JOIN #{ActsAsTaggableOn::Tagging.table_name} #{taggings_alias}" \
|
@@ -145,9 +145,9 @@ module ActsAsTaggableOn::Taggable
|
|
145
145
|
if owned_by
|
146
146
|
tagging_join << ' AND ' +
|
147
147
|
sanitize_sql([
|
148
|
-
|
149
|
-
|
150
|
-
|
148
|
+
"#{taggings_alias}.tagger_id = ? AND #{taggings_alias}.tagger_type = ?",
|
149
|
+
owned_by.id,
|
150
|
+
owned_by.class.base_class.to_s
|
151
151
|
])
|
152
152
|
end
|
153
153
|
|
@@ -159,7 +159,7 @@ module ActsAsTaggableOn::Taggable
|
|
159
159
|
return empty_result unless tags.length == tag_list.length
|
160
160
|
|
161
161
|
tags.each do |tag|
|
162
|
-
taggings_alias = adjust_taggings_alias("#{alias_base_name[0..11]}_taggings_#{sha_prefix(tag.name)}")
|
162
|
+
taggings_alias = adjust_taggings_alias("#{alias_base_name[0..11]}_taggings_#{ActsAsTaggableOn::Utils.sha_prefix(tag.name)}")
|
163
163
|
tagging_join = "JOIN #{ActsAsTaggableOn::Tagging.table_name} #{taggings_alias}" \
|
164
164
|
" ON #{taggings_alias}.taggable_id = #{quote}#{table_name}#{quote}.#{primary_key}" +
|
165
165
|
" AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name, nil)}" +
|
@@ -170,9 +170,9 @@ module ActsAsTaggableOn::Taggable
|
|
170
170
|
if owned_by
|
171
171
|
tagging_join << ' AND ' +
|
172
172
|
sanitize_sql([
|
173
|
-
|
174
|
-
|
175
|
-
|
173
|
+
"#{taggings_alias}.tagger_id = ? AND #{taggings_alias}.tagger_type = ?",
|
174
|
+
owned_by.id,
|
175
|
+
owned_by.class.base_class.to_s
|
176
176
|
])
|
177
177
|
end
|
178
178
|
|
@@ -202,13 +202,13 @@ module ActsAsTaggableOn::Taggable
|
|
202
202
|
|
203
203
|
order_by << options[:order] if options[:order].present?
|
204
204
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
205
|
+
select(select_clause)
|
206
|
+
.joins(joins.join(' '))
|
207
|
+
.where(conditions.join(' AND '))
|
208
|
+
.group(group)
|
209
|
+
.having(having)
|
210
|
+
.order(order_by.join(', '))
|
211
|
+
.readonly(false)
|
212
212
|
end
|
213
213
|
|
214
214
|
def is_taggable?
|
@@ -61,11 +61,11 @@ module ActsAsTaggableOn::Taggable
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def related_where(klass, conditions)
|
64
|
-
klass.select("#{klass.table_name}.*, COUNT(#{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key}) AS count")
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
64
|
+
klass.select("#{klass.table_name}.*, COUNT(#{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key}) AS count")
|
65
|
+
.from("#{klass.table_name}, #{ActsAsTaggableOn::Tag.table_name}, #{ActsAsTaggableOn::Tagging.table_name}")
|
66
|
+
.group(group_columns(klass))
|
67
|
+
.order('count DESC')
|
68
|
+
.where(conditions)
|
69
69
|
end
|
70
70
|
end
|
71
71
|
end
|
@@ -149,9 +149,10 @@ module ActsAsTaggableOn
|
|
149
149
|
|
150
150
|
private
|
151
151
|
|
152
|
-
#
|
152
|
+
# Convert everything to string, remove whitespace, duplicates, and blanks.
|
153
153
|
def clean!
|
154
154
|
reject!(&:blank?)
|
155
|
+
map!(&:to_s)
|
155
156
|
map!(&:strip)
|
156
157
|
map! { |tag| tag.mb_chars.downcase.to_s } if ActsAsTaggableOn.force_lowercase
|
157
158
|
map!(&:parameterize) if ActsAsTaggableOn.force_parameterize
|
@@ -1,62 +1,62 @@
|
|
1
1
|
module ActsAsTaggableOn
|
2
2
|
module Utils
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
3
|
+
class << self
|
4
|
+
# Use ActsAsTaggableOn::Tag connection
|
5
|
+
def connection
|
6
|
+
ActsAsTaggableOn::Tag.connection
|
7
|
+
end
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
def using_postgresql?
|
10
|
+
connection && connection.adapter_name == 'PostgreSQL'
|
11
|
+
end
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
def postgresql_version
|
14
|
+
if using_postgresql?
|
15
|
+
connection.execute('SHOW SERVER_VERSION').first['server_version'].to_f
|
16
|
+
end
|
17
17
|
end
|
18
|
-
end
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
def postgresql_support_json?
|
20
|
+
postgresql_version >= 9.2
|
21
|
+
end
|
23
22
|
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
def using_sqlite?
|
24
|
+
connection && connection.adapter_name == 'SQLite'
|
25
|
+
end
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
27
|
+
def using_mysql?
|
28
|
+
#We should probably use regex for mysql to support prehistoric adapters
|
29
|
+
connection && connection.adapter_name == 'Mysql2'
|
30
|
+
end
|
32
31
|
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
def using_case_insensitive_collation?
|
33
|
+
using_mysql? && connection.collation =~ /_ci\Z/
|
34
|
+
end
|
36
35
|
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
def supports_concurrency?
|
37
|
+
!using_sqlite?
|
38
|
+
end
|
40
39
|
|
41
|
-
|
42
|
-
|
43
|
-
|
40
|
+
def sha_prefix(string)
|
41
|
+
Digest::SHA1.hexdigest("#{string}#{rand}")[0..6]
|
42
|
+
end
|
44
43
|
|
45
|
-
|
46
|
-
|
47
|
-
|
44
|
+
def active_record4?
|
45
|
+
::ActiveRecord::VERSION::MAJOR == 4
|
46
|
+
end
|
48
47
|
|
49
|
-
|
50
|
-
|
51
|
-
|
48
|
+
def active_record42?
|
49
|
+
active_record4? && ::ActiveRecord::VERSION::MINOR >= 2
|
50
|
+
end
|
52
51
|
|
53
|
-
|
54
|
-
|
55
|
-
|
52
|
+
def like_operator
|
53
|
+
using_postgresql? ? 'ILIKE' : 'LIKE'
|
54
|
+
end
|
56
55
|
|
57
|
-
|
58
|
-
|
59
|
-
|
56
|
+
# escape _ and % characters in strings, since these are wildcards in SQL.
|
57
|
+
def escape_like(str)
|
58
|
+
str.gsub(/[!%_]/) { |x| '!' + x }
|
59
|
+
end
|
60
60
|
end
|
61
61
|
end
|
62
62
|
end
|
@@ -3,8 +3,11 @@ require 'spec_helper'
|
|
3
3
|
require 'db/migrate/2_add_missing_unique_indices.rb'
|
4
4
|
|
5
5
|
shared_examples_for 'without unique index' do
|
6
|
-
|
7
|
-
|
6
|
+
prepend_before(:all) { AddMissingUniqueIndices.down }
|
7
|
+
append_after(:all) do
|
8
|
+
ActsAsTaggableOn::Tag.delete_all
|
9
|
+
AddMissingUniqueIndices.up
|
10
|
+
end
|
8
11
|
end
|
9
12
|
|
10
13
|
describe ActsAsTaggableOn::Tag do
|
@@ -14,10 +17,9 @@ describe ActsAsTaggableOn::Tag do
|
|
14
17
|
end
|
15
18
|
|
16
19
|
|
17
|
-
|
18
20
|
describe 'named like any' do
|
19
|
-
|
20
|
-
|
21
|
+
if ActsAsTaggableOn::Utils.using_case_insensitive_collation?
|
22
|
+
context 'case insensitive collation and unique index on tag name' do
|
21
23
|
before(:each) do
|
22
24
|
ActsAsTaggableOn::Tag.create(name: 'Awesome')
|
23
25
|
ActsAsTaggableOn::Tag.create(name: 'epic')
|
@@ -621,8 +621,8 @@ describe 'Taggable' do
|
|
621
621
|
it 'should return all column names joined for Tag GROUP clause' do
|
622
622
|
# NOTE: type column supports an STI Tag subclass in the test suite, though
|
623
623
|
# isn't included by default in the migration generator
|
624
|
-
expect(@taggable.grouped_column_names_for(ActsAsTaggableOn::Tag))
|
625
|
-
|
624
|
+
expect(@taggable.grouped_column_names_for(ActsAsTaggableOn::Tag))
|
625
|
+
.to eq('tags.id, tags.name, tags.taggings_count, tags.type')
|
626
626
|
end
|
627
627
|
|
628
628
|
it 'should return all column names joined for TaggableModel GROUP clause' do
|
@@ -847,33 +847,34 @@ describe 'Taggable' do
|
|
847
847
|
end
|
848
848
|
end
|
849
849
|
|
850
|
-
|
851
850
|
if ActsAsTaggableOn::Utils.using_postgresql?
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
851
|
+
if ActsAsTaggableOn::Utils.postgresql_support_json?
|
852
|
+
describe 'Taggable model with json columns' do
|
853
|
+
before(:each) do
|
854
|
+
@taggable = TaggableModelWithJson.new(:name => 'Bob Jones')
|
855
|
+
@taggables = [@taggable, TaggableModelWithJson.new(:name => 'John Doe')]
|
856
|
+
end
|
857
857
|
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
858
|
+
it 'should be able to find by tag with context' do
|
859
|
+
@taggable.skill_list = 'ruby, rails, css'
|
860
|
+
@taggable.tag_list = 'bob, charlie'
|
861
|
+
@taggable.save
|
862
862
|
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
863
|
+
expect(TaggableModelWithJson.tagged_with('ruby').first).to eq(@taggable)
|
864
|
+
expect(TaggableModelWithJson.tagged_with('ruby, css').first).to eq(@taggable)
|
865
|
+
expect(TaggableModelWithJson.tagged_with('bob', :on => :skills).first).to_not eq(@taggable)
|
866
|
+
expect(TaggableModelWithJson.tagged_with('bob', :on => :tags).first).to eq(@taggable)
|
867
|
+
end
|
868
868
|
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
869
|
+
it 'should be able to find tagged with any tag' do
|
870
|
+
bob = TaggableModelWithJson.create(:name => 'Bob', :tag_list => 'fitter, happier, more productive', :skill_list => 'ruby, rails, css')
|
871
|
+
frank = TaggableModelWithJson.create(:name => 'Frank', :tag_list => 'weaker, depressed, inefficient', :skill_list => 'ruby, rails, css')
|
872
|
+
steve = TaggableModelWithJson.create(:name => 'Steve', :tag_list => 'fitter, happier, more productive', :skill_list => 'c++, java, ruby')
|
873
873
|
|
874
|
-
|
875
|
-
|
876
|
-
|
874
|
+
expect(TaggableModelWithJson.tagged_with(%w(ruby java), :order => 'taggable_model_with_jsons.name', :any => true).to_a).to eq([bob, frank, steve])
|
875
|
+
expect(TaggableModelWithJson.tagged_with(%w(c++ fitter), :order => 'taggable_model_with_jsons.name', :any => true).to_a).to eq([bob, steve])
|
876
|
+
expect(TaggableModelWithJson.tagged_with(%w(depressed css), :order => 'taggable_model_with_jsons.name', :any => true).to_a).to eq([bob, frank])
|
877
|
+
end
|
877
878
|
end
|
878
879
|
end
|
879
880
|
end
|
@@ -1,21 +1,15 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe ActsAsTaggableOn::Utils do
|
4
|
-
describe 'like_operator' do
|
5
|
-
before(:each) do
|
6
|
-
TaggableModel.acts_as_taggable_on(:tags, :languages, :skills, :needs, :offerings)
|
7
|
-
@taggable = TaggableModel.new(name: 'Bob Jones')
|
8
|
-
end
|
9
|
-
|
10
|
-
|
4
|
+
describe '#like_operator' do
|
11
5
|
it 'should return \'ILIKE\' when the adapter is PostgreSQL' do
|
12
|
-
allow(
|
13
|
-
expect(
|
6
|
+
allow(ActsAsTaggableOn::Utils.connection).to receive(:adapter_name) { 'PostgreSQL' }
|
7
|
+
expect(ActsAsTaggableOn::Utils.like_operator).to eq('ILIKE')
|
14
8
|
end
|
15
9
|
|
16
10
|
it 'should return \'LIKE\' when the adapter is not PostgreSQL' do
|
17
|
-
allow(
|
18
|
-
expect(
|
11
|
+
allow(ActsAsTaggableOn::Utils.connection).to receive(:adapter_name) { 'MySQL' }
|
12
|
+
expect(ActsAsTaggableOn::Utils.like_operator).to eq('LIKE')
|
19
13
|
end
|
20
14
|
end
|
21
15
|
end
|
data/spec/internal/db/schema.rb
CHANGED
@@ -86,7 +86,7 @@ ActiveRecord::Schema.define version: 0 do
|
|
86
86
|
t.column :cached_glass_list, :string, array: true
|
87
87
|
end
|
88
88
|
|
89
|
-
if
|
89
|
+
if ActsAsTaggableOn::Utils.postgresql_support_json?
|
90
90
|
create_table :taggable_model_with_jsons, :force => true do |t|
|
91
91
|
t.column :name, :string
|
92
92
|
t.column :type, :string
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts-as-taggable-on
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.2.
|
4
|
+
version: 3.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Bleigh
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-05-
|
12
|
+
date: 2014-05-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -69,16 +69,16 @@ dependencies:
|
|
69
69
|
name: mysql2
|
70
70
|
requirement: !ruby/object:Gem::Requirement
|
71
71
|
requirements:
|
72
|
-
- - "
|
72
|
+
- - ">="
|
73
73
|
- !ruby/object:Gem::Version
|
74
|
-
version: 0
|
74
|
+
version: '0'
|
75
75
|
type: :development
|
76
76
|
prerelease: false
|
77
77
|
version_requirements: !ruby/object:Gem::Requirement
|
78
78
|
requirements:
|
79
|
-
- - "
|
79
|
+
- - ">="
|
80
80
|
- !ruby/object:Gem::Version
|
81
|
-
version: 0
|
81
|
+
version: '0'
|
82
82
|
- !ruby/object:Gem::Dependency
|
83
83
|
name: pg
|
84
84
|
requirement: !ruby/object:Gem::Requirement
|
@@ -99,84 +99,84 @@ dependencies:
|
|
99
99
|
requirements:
|
100
100
|
- - "~>"
|
101
101
|
- !ruby/object:Gem::Version
|
102
|
-
version: 3.0.0.
|
102
|
+
version: 3.0.0.beta2
|
103
103
|
type: :development
|
104
104
|
prerelease: false
|
105
105
|
version_requirements: !ruby/object:Gem::Requirement
|
106
106
|
requirements:
|
107
107
|
- - "~>"
|
108
108
|
- !ruby/object:Gem::Version
|
109
|
-
version: 3.0.0.
|
109
|
+
version: 3.0.0.beta2
|
110
110
|
- !ruby/object:Gem::Dependency
|
111
111
|
name: rspec-its
|
112
112
|
requirement: !ruby/object:Gem::Requirement
|
113
113
|
requirements:
|
114
|
-
- - "
|
114
|
+
- - "~>"
|
115
115
|
- !ruby/object:Gem::Version
|
116
|
-
version: '0'
|
116
|
+
version: '1.0'
|
117
117
|
type: :development
|
118
118
|
prerelease: false
|
119
119
|
version_requirements: !ruby/object:Gem::Requirement
|
120
120
|
requirements:
|
121
|
-
- - "
|
121
|
+
- - "~>"
|
122
122
|
- !ruby/object:Gem::Version
|
123
|
-
version: '0'
|
123
|
+
version: '1.0'
|
124
124
|
- !ruby/object:Gem::Dependency
|
125
125
|
name: rspec
|
126
126
|
requirement: !ruby/object:Gem::Requirement
|
127
127
|
requirements:
|
128
|
-
- -
|
128
|
+
- - '='
|
129
129
|
- !ruby/object:Gem::Version
|
130
|
-
version:
|
130
|
+
version: 3.0.0.beta2
|
131
131
|
type: :development
|
132
132
|
prerelease: false
|
133
133
|
version_requirements: !ruby/object:Gem::Requirement
|
134
134
|
requirements:
|
135
|
-
- -
|
135
|
+
- - '='
|
136
136
|
- !ruby/object:Gem::Version
|
137
|
-
version:
|
137
|
+
version: 3.0.0.beta2
|
138
138
|
- !ruby/object:Gem::Dependency
|
139
139
|
name: ammeter
|
140
140
|
requirement: !ruby/object:Gem::Requirement
|
141
141
|
requirements:
|
142
|
-
- - "
|
142
|
+
- - "~>"
|
143
143
|
- !ruby/object:Gem::Version
|
144
|
-
version: '0'
|
144
|
+
version: '1.0'
|
145
145
|
type: :development
|
146
146
|
prerelease: false
|
147
147
|
version_requirements: !ruby/object:Gem::Requirement
|
148
148
|
requirements:
|
149
|
-
- - "
|
149
|
+
- - "~>"
|
150
150
|
- !ruby/object:Gem::Version
|
151
|
-
version: '0'
|
151
|
+
version: '1.0'
|
152
152
|
- !ruby/object:Gem::Dependency
|
153
153
|
name: barrier
|
154
154
|
requirement: !ruby/object:Gem::Requirement
|
155
155
|
requirements:
|
156
|
-
- - "
|
156
|
+
- - "~>"
|
157
157
|
- !ruby/object:Gem::Version
|
158
|
-
version: '0'
|
158
|
+
version: '1.0'
|
159
159
|
type: :development
|
160
160
|
prerelease: false
|
161
161
|
version_requirements: !ruby/object:Gem::Requirement
|
162
162
|
requirements:
|
163
|
-
- - "
|
163
|
+
- - "~>"
|
164
164
|
- !ruby/object:Gem::Version
|
165
|
-
version: '0'
|
165
|
+
version: '1.0'
|
166
166
|
- !ruby/object:Gem::Dependency
|
167
167
|
name: database_cleaner
|
168
168
|
requirement: !ruby/object:Gem::Requirement
|
169
169
|
requirements:
|
170
|
-
- - "
|
170
|
+
- - "~>"
|
171
171
|
- !ruby/object:Gem::Version
|
172
|
-
version: '
|
172
|
+
version: '1.2'
|
173
173
|
type: :development
|
174
174
|
prerelease: false
|
175
175
|
version_requirements: !ruby/object:Gem::Requirement
|
176
176
|
requirements:
|
177
|
-
- - "
|
177
|
+
- - "~>"
|
178
178
|
- !ruby/object:Gem::Version
|
179
|
-
version: '
|
179
|
+
version: '1.2'
|
180
180
|
description: With ActsAsTaggableOn, you can tag a single model on several contexts,
|
181
181
|
such as skills, interests, and awards. It also provides other advanced functionality.
|
182
182
|
email:
|
@@ -236,7 +236,6 @@ files:
|
|
236
236
|
- spec/acts_as_taggable_on/tagging_spec.rb
|
237
237
|
- spec/acts_as_taggable_on/tags_helper_spec.rb
|
238
238
|
- spec/acts_as_taggable_on/utils_spec.rb
|
239
|
-
- spec/bm.rb
|
240
239
|
- spec/internal/app/models/altered_inheriting_taggable_model.rb
|
241
240
|
- spec/internal/app/models/cached_model.rb
|
242
241
|
- spec/internal/app/models/cached_model_with_array.rb
|
@@ -309,7 +308,6 @@ test_files:
|
|
309
308
|
- spec/acts_as_taggable_on/tagging_spec.rb
|
310
309
|
- spec/acts_as_taggable_on/tags_helper_spec.rb
|
311
310
|
- spec/acts_as_taggable_on/utils_spec.rb
|
312
|
-
- spec/bm.rb
|
313
311
|
- spec/internal/app/models/altered_inheriting_taggable_model.rb
|
314
312
|
- spec/internal/app/models/cached_model.rb
|
315
313
|
- spec/internal/app/models/cached_model_with_array.rb
|
data/spec/bm.rb
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
require 'active_record'
|
2
|
-
require 'action_view'
|
3
|
-
require File.expand_path('../../lib/acts-as-taggable-on', __FILE__)
|
4
|
-
|
5
|
-
if defined?(ActiveRecord::Acts::TaggableOn)
|
6
|
-
ActiveRecord::Base.send :include, ActiveRecord::Acts::TaggableOn
|
7
|
-
ActiveRecord::Base.send :include, ActiveRecord::Acts::Tagger
|
8
|
-
ActionView::Base.send :include, TagsHelper if defined?(ActionView::Base)
|
9
|
-
end
|
10
|
-
|
11
|
-
TEST_DATABASE_FILE = File.join(File.dirname(__FILE__), '..', 'test.sqlite3')
|
12
|
-
File.unlink(TEST_DATABASE_FILE) if File.exist?(TEST_DATABASE_FILE)
|
13
|
-
ActiveRecord::Base.establish_connection :adapter => 'sqlite3', :database => TEST_DATABASE_FILE
|
14
|
-
|
15
|
-
ActiveRecord::Base.silence do
|
16
|
-
ActiveRecord::Migration.verbose = false
|
17
|
-
ActiveRecord::Schema.define :version => 0 do
|
18
|
-
create_table "taggings", :force => true do |t|
|
19
|
-
t.integer "tag_id", :limit => 11
|
20
|
-
t.integer "taggable_id", :limit => 11
|
21
|
-
t.string "taggable_type"
|
22
|
-
t.string "context"
|
23
|
-
t.datetime "created_at"
|
24
|
-
t.integer "tagger_id", :limit => 11
|
25
|
-
t.string "tagger_type"
|
26
|
-
end
|
27
|
-
|
28
|
-
add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id"
|
29
|
-
add_index "taggings", ["taggable_id", "taggable_type", "context"], :name => "index_taggings_on_taggable_id_and_taggable_type_and_context"
|
30
|
-
|
31
|
-
create_table "tags", :force => true do |t|
|
32
|
-
t.string "name"
|
33
|
-
end
|
34
|
-
|
35
|
-
create_table :taggable_models, :force => true do |t|
|
36
|
-
t.column :name, :string
|
37
|
-
t.column :type, :string
|
38
|
-
t.column :cached_tag_list, :string
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
class TaggableModel < ActiveRecord::Base
|
43
|
-
acts_as_taggable
|
44
|
-
acts_as_taggable_on :languages
|
45
|
-
acts_as_taggable_on :skills
|
46
|
-
acts_as_taggable_on :needs, :offerings
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
puts Benchmark.measure {
|
51
|
-
1000.times { TaggableModel.create :tag_list => "awesome, epic, neat" }
|
52
|
-
}
|