acts-as-taggable-on 2.0.0.pre3 → 2.0.0.pre4

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.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.0.pre3
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 InstanceMethods
5
- base.extend ClassMethods
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 save_tags
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
- # Destroy old taggings:
60
- Tagging.destroy_all(:id => old_taggings.map(&:id))
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 InstanceMethods
5
- base.extend ClassMethods
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 %(
@@ -20,9 +20,6 @@ module ActsAsTaggableOn
20
20
  end
21
21
 
22
22
  module InstanceMethods
23
- def self.included(base)
24
- end
25
-
26
23
  def tag(taggable, opts={})
27
24
  opts.reverse_merge!(:force => true)
28
25
 
@@ -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 => :foo)
68
- @tagger.tag(@taggable, :with => '', :on => :foo)
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.new
7
- @taggable = TaggableModel.new(:name => "Bob Jones")
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 or lose tags from different users" do
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 == 6
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
- it "should not lose tags" do
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
- [@taggable, @user].each(&:reload)
42
- @taggable.tag_list.should == %w(ruby)
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
- @taggable.update_attributes(:tag_list => "")
64
+ @user2.tag(@taggable, :with => 'epic', :on => :tags)
47
65
  }.should change(Tagging, :count).by(-1)
48
-
49
- @taggable.tag_list.should == []
50
- @taggable.all_tags_list.sort.should == %w(ruby scheme).sort
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
@@ -31,4 +31,8 @@ ActiveRecord::Schema.define :version => 0 do
31
31
  t.column :type, :string
32
32
  #t.column :cached_tag_list, :string
33
33
  end
34
+
35
+ create_table :untaggable_models, :force => true do |t|
36
+ t.column :name, :string
37
+ end
34
38
  end
@@ -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
- prerelease: true
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.6
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.