johnsbrn-acts-as-taggable-on 1.0.5 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,4 @@
1
1
  ---
2
- :patch: 5
2
+ :patch: 0
3
3
  :major: 1
4
- :minor: 0
4
+ :minor: 1
@@ -22,7 +22,7 @@ module ActiveRecord
22
22
  self.class_eval do
23
23
  has_many "#{tag_type.singularize}_taggings".to_sym, :as => :taggable, :dependent => :destroy,
24
24
  :include => :tag, :conditions => ["context = ?",tag_type], :class_name => "Tagging"
25
- has_many "#{tag_type}".to_sym, :through => "#{tag_type.singularize}_taggings".to_sym, :source => :tag
25
+ has_many "#{tag_type}".to_sym, :through => "#{tag_type.singularize}_taggings".to_sym, :source => :tag, :order => Tagging.column_names.include?("position") ? "taggings.position ASC" : nil
26
26
  end
27
27
 
28
28
  self.class_eval <<-RUBY
@@ -242,6 +242,7 @@ module ActiveRecord
242
242
  else
243
243
  opts = {:conditions => ["context = ?", context.to_s]}
244
244
  end
245
+ opts.merge!(:order => "taggings.position ASC") if Tagging.column_names.include?("position")
245
246
  base_tags.find(:all, opts)
246
247
  end
247
248
 
@@ -266,10 +267,11 @@ module ActiveRecord
266
267
 
267
268
  def related_search_options(context, klass, options = {})
268
269
  tags_to_find = self.tags_on(context).collect { |t| t.name }
269
-
270
+
271
+ exclude_self = "#{klass.table_name}.id != #{self.id} AND" if self.class == klass
270
272
  { :select => "#{klass.table_name}.*, COUNT(#{Tag.table_name}.id) AS count",
271
273
  :from => "#{klass.table_name}, #{Tag.table_name}, #{Tagging.table_name}",
272
- :conditions => ["#{klass.table_name}.id = #{Tagging.table_name}.taggable_id AND #{Tagging.table_name}.taggable_type = '#{klass.to_s}' AND #{Tagging.table_name}.tag_id = #{Tag.table_name}.id AND #{Tag.table_name}.name IN (?)", tags_to_find],
274
+ :conditions => ["#{exclude_self} #{klass.table_name}.id = #{Tagging.table_name}.taggable_id AND #{Tagging.table_name}.taggable_type = '#{klass.to_s}' AND #{Tagging.table_name}.tag_id = #{Tag.table_name}.id AND #{Tag.table_name}.name IN (?)", tags_to_find],
273
275
  :group => "#{klass.table_name}.id",
274
276
  :order => "count DESC"
275
277
  }.update(options)
@@ -287,15 +289,25 @@ module ActiveRecord
287
289
  (custom_contexts + self.class.tag_types.map(&:to_s)).each do |tag_type|
288
290
  next unless instance_variable_get("@#{tag_type.singularize}_list")
289
291
  owner = instance_variable_get("@#{tag_type.singularize}_list").owner
290
- new_tag_names = instance_variable_get("@#{tag_type.singularize}_list") - tags_on(tag_type).map(&:name)
292
+ all_tag_names = instance_variable_get("@#{tag_type.singularize}_list")
293
+ new_tag_names = all_tag_names - tags_on(tag_type).map(&:name)
291
294
  old_tags = tags_on(tag_type).reject { |tag| instance_variable_get("@#{tag_type.singularize}_list").include?(tag.name) }
292
295
 
293
296
  self.class.transaction do
294
297
  base_tags.delete(*old_tags) if old_tags.any?
295
- new_tag_names.each do |new_tag_name|
298
+ all_tag_names.each_index do |index|
299
+ new_tag_name = all_tag_names[index]
296
300
  new_tag = Tag.find_or_create_with_like_by_name(new_tag_name)
297
- Tagging.create(:tag_id => new_tag.id, :context => tag_type,
298
- :taggable => self, :tagger => owner)
301
+ if new_tag.name != new_tag_name
302
+ new_tag.name = new_tag_name
303
+ new_tag.save
304
+ end
305
+ tagging =
306
+ taggings.find(:first, :conditions => {:tag_id => new_tag.id, :context => tag_type}) ||
307
+ Tagging.new(:tag_id => new_tag.id, :context => tag_type,
308
+ :taggable => self, :tagger => owner)
309
+ tagging.position = index if tagging.respond_to?(:position)
310
+ tagging.save
299
311
  end
300
312
  end
301
313
  end
@@ -9,7 +9,7 @@ module ActiveRecord
9
9
  def acts_as_tagger(opts={})
10
10
  has_many :owned_taggings, opts.merge(:as => :tagger, :dependent => :destroy,
11
11
  :include => :tag, :class_name => "Tagging")
12
- has_many :owned_tags, :through => :owned_taggings, :source => :tag
12
+ has_many :owned_tags, :through => :owned_taggings, :source => :tag, :uniq => true
13
13
  include ActiveRecord::Acts::Tagger::InstanceMethods
14
14
  extend ActiveRecord::Acts::Tagger::SingletonMethods
15
15
  end
@@ -49,4 +49,4 @@ module ActiveRecord
49
49
 
50
50
  end
51
51
  end
52
- end
52
+ end
@@ -103,6 +103,20 @@ describe "Acts As Taggable On" do
103
103
  taggable1.find_related_tags_for(OtherTaggableModel).should include(taggable3)
104
104
  taggable1.find_related_tags_for(OtherTaggableModel).should_not include(taggable2)
105
105
  end
106
+
107
+ it "should not include the object itself in the list of related objects" do
108
+ taggable1 = TaggableModel.create!(:name => "Taggable 1")
109
+ taggable2 = TaggableModel.create!(:name => "Taggable 2")
110
+
111
+ taggable1.tag_list = "one"
112
+ taggable1.save
113
+
114
+ taggable2.tag_list = "one, two"
115
+ taggable2.save
116
+
117
+ taggable1.find_related_tags.should include(taggable2)
118
+ taggable1.find_related_tags.should_not include(taggable1)
119
+ end
106
120
  end
107
121
 
108
122
  describe 'Tagging Contexts' do
@@ -148,4 +162,43 @@ describe "Acts As Taggable On" do
148
162
  end
149
163
  end
150
164
 
165
+ describe "Tag Handling" do
166
+ it "should save case changes" do
167
+ taggable1 = TaggableModel.create!(:name => "Taggable 1")
168
+
169
+ taggable1.tag_list = "one, two"
170
+ taggable1.save
171
+
172
+ taggable1.tag_list.should include("one")
173
+ taggable1.tag_list.should include("two")
174
+ taggable1.tag_list.should_not include("One")
175
+ taggable1.tag_list.should_not include("Two")
176
+
177
+ taggable1.tag_list = "One, Two"
178
+ taggable1.save
179
+ taggable1.reload
180
+
181
+ taggable1.tag_list.should include("One")
182
+ taggable1.tag_list.should include("Two")
183
+ taggable1.tag_list.should_not include("one")
184
+ taggable1.tag_list.should_not include("two")
185
+ end
186
+
187
+ it "should order tags if there is a position column" do
188
+ taggable1 = TaggableModel.create!(:name => "Taggable 1")
189
+ Tagging.column_names.should include("position")
190
+
191
+ taggable1.tag_list = "one, two"
192
+ taggable1.save
193
+ taggable1.reload
194
+ taggable1.tag_list.should == ["one", "two"]
195
+
196
+ taggable1.tag_list = "two, one"
197
+ taggable1.save
198
+ taggable1.reload
199
+
200
+ taggable1.tag_list.should == ["two", "one"]
201
+ end
202
+
203
+ end
151
204
  end
@@ -7,9 +7,10 @@ describe Tag do
7
7
  end
8
8
 
9
9
  it "should require a name" do
10
- @tag.should have(1).errors_on(:name)
10
+ @tag.should_not be_valid
11
+ @tag.should have(1).error
11
12
  @tag.name = "something"
12
- @tag.should have(0).errors_on(:name)
13
+ @tag.should be_valid
13
14
  end
14
15
 
15
16
  it "should equal a tag with the same name" do
@@ -22,4 +23,5 @@ describe Tag do
22
23
  @tag.name = "cool"
23
24
  @tag.to_s.should == "cool"
24
25
  end
26
+
25
27
  end
@@ -7,6 +7,7 @@ ActiveRecord::Schema.define :version => 0 do
7
7
  t.datetime "created_at"
8
8
  t.integer "tagger_id", :limit => 11
9
9
  t.string "tagger_type"
10
+ t.integer "position", :limit => 11
10
11
  end
11
12
 
12
13
  add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id"
@@ -1,12 +1,25 @@
1
- require File.dirname(__FILE__) + '/../../../../spec/spec_helper'
1
+ # To run these specs on a live Rails App, you'll have to change
2
+ # the following requirements. Chances are, you want to replace
3
+ # ALL of the following code with "require /my/rails/app/spec/spec_helper"
4
+
5
+ require 'rubygems'
6
+ require 'activerecord'
7
+ ActiveRecord::Base.establish_connection(:adapter => 'sqlite3',
8
+ :database => ':memory:',
9
+ :timeout => 5000,
10
+ :encoding => 'utf8')
11
+
12
+ plugin_spec_dir = File.dirname(__FILE__)
13
+ Object::RAILS_DEFAULT_LOGGER = ActiveRecord::Base.logger = Logger.new(plugin_spec_dir + "/debug.log")
14
+
15
+ $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
16
+
17
+ require File.join(File.dirname(__FILE__), '..', 'lib/acts-as-taggable-on')
2
18
 
3
19
  module Spec::Example::ExampleGroupMethods
4
20
  alias :context :describe
5
21
  end
6
22
 
7
- plugin_spec_dir = File.dirname(__FILE__)
8
- ActiveRecord::Base.logger = Logger.new(plugin_spec_dir + "/debug.log")
9
-
10
23
  load(File.dirname(__FILE__) + '/schema.rb')
11
24
 
12
25
  class TaggableModel < ActiveRecord::Base
@@ -30,4 +43,4 @@ class TaggableUser < ActiveRecord::Base
30
43
  end
31
44
 
32
45
  class UntaggableModel < ActiveRecord::Base
33
- end
46
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: johnsbrn-acts-as-taggable-on
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Bleigh
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-01-26 00:00:00 -08:00
12
+ date: 2009-03-07 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -36,7 +36,6 @@ files:
36
36
  - lib/acts_as_taggable_on/tagging.rb
37
37
  - lib/acts_as_taggable_on/tags_helper.rb
38
38
  - lib/autotest
39
- - lib/autotest/discover.rb
40
39
  - spec/acts_as_taggable_on
41
40
  - spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb
42
41
  - spec/acts_as_taggable_on/acts_as_tagger_spec.rb
@@ -45,6 +44,7 @@ files:
45
44
  - spec/acts_as_taggable_on/taggable_spec.rb
46
45
  - spec/acts_as_taggable_on/tagger_spec.rb
47
46
  - spec/acts_as_taggable_on/tagging_spec.rb
47
+ - spec/debug.log
48
48
  - spec/schema.rb
49
49
  - spec/spec.opts
50
50
  - spec/spec_helper.rb
@@ -1,6 +0,0 @@
1
- # Need this to get picked up by autotest?
2
- $:.push(File.join(File.dirname(__FILE__), %w[.. .. rspec]))
3
-
4
- Autotest.add_discovery do
5
- "rspec"
6
- end