acts-as-taggable-on 2.0.0.pre3 → 2.0.0.pre4
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/acts_as_taggable_on/acts_as_taggable_on.rb +5 -5
- data/lib/acts_as_taggable_on/acts_as_taggable_on/aggregate.rb +4 -2
- data/lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb +3 -3
- data/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb +16 -6
- data/lib/acts_as_taggable_on/acts_as_taggable_on/ownership.rb +35 -15
- data/lib/acts_as_taggable_on/acts_as_taggable_on/related.rb +4 -2
- data/lib/acts_as_taggable_on/acts_as_tagger.rb +0 -3
- data/rails/init.rb +1 -0
- data/spec/acts_as_taggable_on/acts_as_tagger_spec.rb +3 -2
- data/spec/acts_as_taggable_on/tagger_spec.rb +33 -14
- data/spec/schema.rb +4 -0
- data/spec/spec_helper.rb +3 -2
- metadata +5 -14
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.0.0.
|
1
|
+
2.0.0.pre4
|
@@ -31,11 +31,11 @@ module ActsAsTaggableOn
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
include Core
|
35
|
-
include Aggregate
|
36
|
-
include Cache
|
37
|
-
include Ownership
|
38
|
-
include Related
|
34
|
+
include ActsAsTaggableOn::Taggable::Core
|
35
|
+
include ActsAsTaggableOn::Taggable::Aggregate
|
36
|
+
include ActsAsTaggableOn::Taggable::Cache
|
37
|
+
include ActsAsTaggableOn::Taggable::Ownership
|
38
|
+
include ActsAsTaggableOn::Taggable::Related
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
@@ -1,8 +1,10 @@
|
|
1
1
|
module ActsAsTaggableOn::Taggable
|
2
2
|
module Aggregate
|
3
3
|
def self.included(base)
|
4
|
-
include
|
5
|
-
|
4
|
+
unless base.ancestors.include?(ActsAsTaggableOn::Taggable::Aggregate::InstanceMethods)
|
5
|
+
base.send :include, ActsAsTaggableOn::Taggable::Aggregate::InstanceMethods
|
6
|
+
base.extend ActsAsTaggableOn::Taggable::Aggregate::ClassMethods
|
7
|
+
end
|
6
8
|
|
7
9
|
base.tag_types.map(&:to_s).each do |tag_type|
|
8
10
|
base.class_eval %(
|
@@ -3,6 +3,9 @@ module ActsAsTaggableOn::Taggable
|
|
3
3
|
def self.included(base)
|
4
4
|
# Skip adding caching capabilities if no cache columns exist
|
5
5
|
return unless base.tag_types.any? { |context| base.column_names.include?("cached_#{context.to_s.singularize}_list") }
|
6
|
+
|
7
|
+
base.send :include, ActsAsTaggableOn::Taggable::Cache::InstanceMethods
|
8
|
+
base.extend ActsAsTaggableOn::Taggable::Cache::ClassMethods
|
6
9
|
|
7
10
|
base.class_eval do
|
8
11
|
before_save :save_cached_tag_list
|
@@ -15,9 +18,6 @@ module ActsAsTaggableOn::Taggable
|
|
15
18
|
end
|
16
19
|
)
|
17
20
|
end
|
18
|
-
|
19
|
-
base.extend ClassMethods
|
20
|
-
include InstanceMethods
|
21
21
|
end
|
22
22
|
|
23
23
|
module ClassMethods
|
@@ -1,6 +1,9 @@
|
|
1
1
|
module ActsAsTaggableOn::Taggable
|
2
2
|
module Core
|
3
3
|
def self.included(base)
|
4
|
+
base.send :include, ActsAsTaggableOn::Taggable::Core::InstanceMethods
|
5
|
+
base.extend ActsAsTaggableOn::Taggable::Core::ClassMethods
|
6
|
+
|
4
7
|
base.class_eval do
|
5
8
|
attr_writer :custom_contexts
|
6
9
|
|
@@ -39,9 +42,6 @@ module ActsAsTaggableOn::Taggable
|
|
39
42
|
end
|
40
43
|
)
|
41
44
|
end
|
42
|
-
|
43
|
-
base.extend ClassMethods
|
44
|
-
include InstanceMethods
|
45
45
|
end
|
46
46
|
|
47
47
|
module ClassMethods
|
@@ -142,6 +142,7 @@ module ActsAsTaggableOn::Taggable
|
|
142
142
|
def all_tags_list_on(context)
|
143
143
|
variable_name = "@all_#{context.to_s.singularize}_list"
|
144
144
|
return instance_variable_get(variable_name) if instance_variable_get(variable_name)
|
145
|
+
|
145
146
|
instance_variable_set(variable_name, TagList.new(all_tags_on(context).map(&:name)).freeze)
|
146
147
|
end
|
147
148
|
|
@@ -149,7 +150,7 @@ module ActsAsTaggableOn::Taggable
|
|
149
150
|
# Returns all tags of a given context
|
150
151
|
def all_tags_on(context)
|
151
152
|
opts = ["#{Tagging.table_name}.context = ?", context.to_s]
|
152
|
-
base_tags.where(opts).order("#{Tagging.table_name}.created_at")
|
153
|
+
base_tags.where(opts).order("#{Tagging.table_name}.created_at").group("#{Tagging.table_name}.tag_id").all
|
153
154
|
end
|
154
155
|
|
155
156
|
##
|
@@ -169,6 +170,15 @@ module ActsAsTaggableOn::Taggable
|
|
169
170
|
custom_contexts + self.class.tag_types.map(&:to_s)
|
170
171
|
end
|
171
172
|
|
173
|
+
def reload
|
174
|
+
self.class.tag_types.each do |context|
|
175
|
+
instance_variable_set("@#{context.to_s.singularize}_list", nil)
|
176
|
+
instance_variable_set("@all_#{context.to_s.singularize}_list", nil)
|
177
|
+
end
|
178
|
+
|
179
|
+
super
|
180
|
+
end
|
181
|
+
|
172
182
|
def save_tags
|
173
183
|
transaction do
|
174
184
|
tagging_contexts.each do |context|
|
@@ -184,13 +194,13 @@ module ActsAsTaggableOn::Taggable
|
|
184
194
|
# Find taggings to remove:
|
185
195
|
old_taggings = Tagging.where(:taggable_id => self.id, :taggable_type => self.class.base_class.to_s,
|
186
196
|
:tagger_type => nil, :tagger_id => nil,
|
187
|
-
:context => context, :tag_id => old_tags)
|
197
|
+
:context => context.to_s, :tag_id => old_tags)
|
188
198
|
|
189
199
|
Tagging.destroy_all :id => old_taggings.map(&:id)
|
190
200
|
|
191
201
|
# Create new taggings:
|
192
202
|
new_tags.each do |tag|
|
193
|
-
Tagging.create!(:tag_id => tag.id, :context => context, :taggable => self)
|
203
|
+
Tagging.create!(:tag_id => tag.id, :context => context.to_s, :taggable => self)
|
194
204
|
end
|
195
205
|
end
|
196
206
|
end
|
@@ -1,8 +1,12 @@
|
|
1
1
|
module ActsAsTaggableOn::Taggable
|
2
2
|
module Ownership
|
3
3
|
def self.included(base)
|
4
|
-
include InstanceMethods
|
5
|
-
base.extend ClassMethods
|
4
|
+
base.send :include, ActsAsTaggableOn::Taggable::Ownership::InstanceMethods
|
5
|
+
base.extend ActsAsTaggableOn::Taggable::Ownership::ClassMethods
|
6
|
+
|
7
|
+
base.class_eval do
|
8
|
+
after_save :save_owned_tags
|
9
|
+
end
|
6
10
|
|
7
11
|
base.tag_types.map(&:to_s).each do |tag_type|
|
8
12
|
base.class_eval %(
|
@@ -17,34 +21,50 @@ module ActsAsTaggableOn::Taggable
|
|
17
21
|
end
|
18
22
|
|
19
23
|
module InstanceMethods
|
24
|
+
def owner_tags_on(owner, context)
|
25
|
+
base_tags.where([%(#{Tagging.table_name}.context = ? AND
|
26
|
+
#{Tagging.table_name}.tagger_id = ? AND
|
27
|
+
#{Tagging.table_name}.tagger_type = ?), context.to_s, owner.id, owner.class.to_s]).all
|
28
|
+
end
|
29
|
+
|
20
30
|
def cached_owned_tag_list_on(context)
|
21
31
|
variable_name = "@owned_#{context}_list"
|
22
32
|
cache = instance_variable_get(variable_name) || instance_variable_set(variable_name, {})
|
23
33
|
end
|
24
34
|
|
25
35
|
def owner_tag_list_on(owner, context)
|
36
|
+
add_custom_context(context)
|
37
|
+
|
26
38
|
cache = cached_owned_tag_list_on(context)
|
39
|
+
cache.delete_if { |key, value| key.id == owner.id && key.class == owner.class }
|
40
|
+
|
27
41
|
cache[owner] ||= TagList.new(*owner_tags_on(owner, context).map(&:name))
|
28
42
|
end
|
29
|
-
|
30
|
-
def owner_tags_on(owner, context)
|
31
|
-
base_tags.where([%(#{Tagging.table_name}.context = ? AND
|
32
|
-
#{Tagging.table_name}.tagger_id = ? AND
|
33
|
-
#{Tagging.table_name}.tagger_type = ?), context.to_s, owner.id, owner.class.to_s])
|
34
|
-
end
|
35
43
|
|
36
44
|
def set_owner_tag_list_on(owner, context, new_list)
|
45
|
+
add_custom_context(context)
|
46
|
+
|
37
47
|
cache = cached_owned_tag_list_on(context)
|
48
|
+
cache.delete_if { |key, value| key.id == owner.id && key.class == owner.class }
|
49
|
+
|
38
50
|
cache[owner] = TagList.from(new_list)
|
39
51
|
end
|
52
|
+
|
53
|
+
def reload
|
54
|
+
self.class.tag_types.each do |context|
|
55
|
+
instance_variable_set("@owned_#{context}_list", nil)
|
56
|
+
end
|
57
|
+
|
58
|
+
super
|
59
|
+
end
|
40
60
|
|
41
|
-
def
|
61
|
+
def save_owned_tags
|
42
62
|
transaction do
|
43
63
|
tagging_contexts.each do |context|
|
44
64
|
cached_owned_tag_list_on(context).each do |owner, tag_list|
|
45
65
|
# Find existing tags or create non-existing tags:
|
46
66
|
tag_list = Tag.find_or_create_all_with_like_by_name(tag_list.uniq)
|
47
|
-
|
67
|
+
|
48
68
|
owned_tags = owner_tags_on(owner, context)
|
49
69
|
|
50
70
|
old_tags = owned_tags - tag_list
|
@@ -56,17 +76,17 @@ module ActsAsTaggableOn::Taggable
|
|
56
76
|
:tagger_type => owner.class.to_s, :tagger_id => owner.id,
|
57
77
|
:tag_id => old_tags, :context => context)
|
58
78
|
|
59
|
-
|
60
|
-
|
79
|
+
if old_taggings.present?
|
80
|
+
# Destroy old taggings:
|
81
|
+
Tagging.destroy_all(:id => old_taggings.map(&:id))
|
82
|
+
end
|
61
83
|
|
62
84
|
# Create new taggings:
|
63
85
|
new_tags.each do |tag|
|
64
|
-
Tagging.create!(:tag_id => tag.id, :context => context, :tagger => owner, :taggable => self)
|
86
|
+
Tagging.create!(:tag_id => tag.id, :context => context.to_s, :tagger => owner, :taggable => self)
|
65
87
|
end
|
66
88
|
end
|
67
89
|
end
|
68
|
-
|
69
|
-
super
|
70
90
|
end
|
71
91
|
end
|
72
92
|
end
|
@@ -1,8 +1,10 @@
|
|
1
1
|
module ActsAsTaggableOn::Taggable
|
2
2
|
module Related
|
3
3
|
def self.included(base)
|
4
|
-
include
|
5
|
-
|
4
|
+
unless base.ancestors.include?(ActsAsTaggableOn::Taggable::Related::InstanceMethods)
|
5
|
+
base.send :include, ActsAsTaggableOn::Taggable::Related::InstanceMethods
|
6
|
+
base.extend ActsAsTaggableOn::Taggable::Related::ClassMethods
|
7
|
+
end
|
6
8
|
|
7
9
|
base.tag_types.map(&:to_s).each do |tag_type|
|
8
10
|
base.class_eval %(
|
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'acts-as-taggable-on'
|
@@ -64,8 +64,9 @@ describe "acts_as_tagger" do
|
|
64
64
|
|
65
65
|
it "should not add owned tags to the common list" do
|
66
66
|
@taggable.tag_list = 'ruby, python'
|
67
|
-
@tagger.tag(@taggable, :with => 'java, lisp', :on => :
|
68
|
-
@
|
67
|
+
@tagger.tag(@taggable, :with => 'java, lisp', :on => :tags)
|
68
|
+
@taggable.tag_list.should == %w(ruby python)
|
69
|
+
@tagger.tag(@taggable, :with => '', :on => :tags)
|
69
70
|
@taggable.tag_list.should == %w(ruby python)
|
70
71
|
end
|
71
72
|
|
@@ -3,8 +3,8 @@ require File.dirname(__FILE__) + '/../spec_helper'
|
|
3
3
|
describe "Tagger" do
|
4
4
|
before(:each) do
|
5
5
|
clean_database!
|
6
|
-
@user = TaggableUser.
|
7
|
-
@taggable = TaggableModel.
|
6
|
+
@user = TaggableUser.create
|
7
|
+
@taggable = TaggableModel.create(:name => "Bob Jones")
|
8
8
|
end
|
9
9
|
|
10
10
|
it "should have taggings" do
|
@@ -17,13 +17,15 @@ describe "Tagger" do
|
|
17
17
|
@user.owned_tags.size == 2
|
18
18
|
end
|
19
19
|
|
20
|
-
it "should not overlap
|
20
|
+
it "should not overlap tags from different taggers" do
|
21
21
|
@user2 = TaggableUser.new
|
22
22
|
lambda{
|
23
23
|
@user.tag(@taggable, :with => 'ruby, scheme', :on => :tags)
|
24
24
|
@user2.tag(@taggable, :with => 'java, python, lisp, ruby', :on => :tags)
|
25
25
|
}.should change(Tagging, :count).by(6)
|
26
26
|
|
27
|
+
[@user, @user2, @taggable].each(&:reload)
|
28
|
+
|
27
29
|
@user.owned_tags.map(&:name).sort.should == %w(ruby scheme).sort
|
28
30
|
@user2.owned_tags.map(&:name).sort.should == %w(java python lisp ruby).sort
|
29
31
|
|
@@ -31,23 +33,40 @@ describe "Tagger" do
|
|
31
33
|
@taggable.tags_from(@user2).sort.should == %w(java lisp python ruby).sort
|
32
34
|
|
33
35
|
@taggable.all_tags_list.sort.should == %w(ruby scheme java python lisp).sort
|
34
|
-
@taggable.all_tags_on(:tags).size.should ==
|
36
|
+
@taggable.all_tags_on(:tags).size.should == 5
|
35
37
|
end
|
38
|
+
|
39
|
+
it "should not lose tags from different taggers" do
|
40
|
+
@user2 = TaggableUser.create
|
41
|
+
@user2.tag(@taggable, :with => 'java, python, lisp, ruby', :on => :tags)
|
42
|
+
@user.tag(@taggable, :with => 'ruby, scheme', :on => :tags)
|
43
|
+
|
44
|
+
lambda {
|
45
|
+
@user2.tag(@taggable, :with => 'java, python, lisp', :on => :tags)
|
46
|
+
}.should change(Tagging, :count).by(-1)
|
36
47
|
|
37
|
-
|
38
|
-
@taggable.update_attributes(:tag_list => 'ruby')
|
39
|
-
@user.tag(@taggable, :with => 'ruby, scheme', :on => :tags)
|
48
|
+
[@user, @user2, @taggable].each(&:reload)
|
40
49
|
|
41
|
-
|
42
|
-
@taggable.
|
43
|
-
@taggable.all_tags_list.sort.should == %w(ruby scheme).sort
|
50
|
+
@taggable.tags_from(@user).sort.should == %w(ruby scheme).sort
|
51
|
+
@taggable.tags_from(@user2).sort.should == %w(java python lisp).sort
|
44
52
|
|
53
|
+
@taggable.all_tags_list.sort.should == %w(ruby scheme java python lisp).sort
|
54
|
+
@taggable.all_tags_on(:tags).length.should == 5
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should not lose tags" do
|
58
|
+
@user2 = TaggableUser.create
|
59
|
+
|
60
|
+
@user.tag(@taggable, :with => 'awesome', :on => :tags)
|
61
|
+
@user2.tag(@taggable, :with => 'awesome, epic', :on => :tags)
|
62
|
+
|
45
63
|
lambda {
|
46
|
-
@
|
64
|
+
@user2.tag(@taggable, :with => 'epic', :on => :tags)
|
47
65
|
}.should change(Tagging, :count).by(-1)
|
48
|
-
|
49
|
-
@taggable.
|
50
|
-
@taggable.all_tags_list.
|
66
|
+
|
67
|
+
@taggable.reload
|
68
|
+
@taggable.all_tags_list.should include('awesome')
|
69
|
+
@taggable.all_tags_list.should include('epic')
|
51
70
|
end
|
52
71
|
|
53
72
|
it "is tagger" do
|
data/spec/schema.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -37,10 +37,11 @@ ActiveRecord::Base.silence do
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def clean_database!
|
40
|
-
$debug = false
|
41
40
|
models = [Tag, Tagging, TaggableModel, OtherTaggableModel, InheritingTaggableModel,
|
42
|
-
AlteredInheritingTaggableModel, TaggableUser]
|
41
|
+
AlteredInheritingTaggableModel, TaggableUser, UntaggableModel]
|
43
42
|
models.each do |model|
|
44
43
|
model.destroy_all
|
45
44
|
end
|
46
45
|
end
|
46
|
+
|
47
|
+
clean_database!
|
metadata
CHANGED
@@ -1,13 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts-as-taggable-on
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
segments:
|
6
|
-
- 2
|
7
|
-
- 0
|
8
|
-
- 0
|
9
|
-
- pre3
|
10
|
-
version: 2.0.0.pre3
|
4
|
+
version: 2.0.0.pre4
|
11
5
|
platform: ruby
|
12
6
|
authors:
|
13
7
|
- Michael Bleigh
|
@@ -52,6 +46,7 @@ files:
|
|
52
46
|
- lib/acts_as_taggable_on/tags_helper.rb
|
53
47
|
- lib/generators/acts_as_taggable_on/migration/migration_generator.rb
|
54
48
|
- lib/generators/acts_as_taggable_on/migration/templates/active_record/migration.rb
|
49
|
+
- rails/init.rb
|
55
50
|
- spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb
|
56
51
|
- spec/acts_as_taggable_on/acts_as_tagger_spec.rb
|
57
52
|
- spec/acts_as_taggable_on/tag_list_spec.rb
|
@@ -77,22 +72,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
77
72
|
requirements:
|
78
73
|
- - ">="
|
79
74
|
- !ruby/object:Gem::Version
|
80
|
-
segments:
|
81
|
-
- 0
|
82
75
|
version: "0"
|
76
|
+
version:
|
83
77
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
78
|
requirements:
|
85
79
|
- - ">"
|
86
80
|
- !ruby/object:Gem::Version
|
87
|
-
segments:
|
88
|
-
- 1
|
89
|
-
- 3
|
90
|
-
- 1
|
91
81
|
version: 1.3.1
|
82
|
+
version:
|
92
83
|
requirements: []
|
93
84
|
|
94
85
|
rubyforge_project:
|
95
|
-
rubygems_version: 1.3.
|
86
|
+
rubygems_version: 1.3.5
|
96
87
|
signing_key:
|
97
88
|
specification_version: 3
|
98
89
|
summary: ActsAsTaggableOn is a tagging plugin for Rails that provides multiple tagging contexts on a single model.
|