dm-tags 0.9.10 → 0.9.11

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,6 +1,20 @@
1
+ === 0.9.11 / 2009-03-29
2
+
3
+ Change frozen_tag_list property to Text
4
+
5
+ * 3 minor enhancements:
6
+
7
+ * Added add_tag(string) for convenient adding of tags
8
+ * Added tag_collection method to allow easy adding/editing of tags
9
+ * Added callback to destroy orphaned taggings
10
+
11
+ * 1 bug fix:
12
+
13
+ * Fix bug in add_tag where exisiting tags would be overwritten
14
+
1
15
  === 0.9.10 / 2009-01-19
2
16
 
3
- * No changes this version
17
+ * No changes this version
4
18
 
5
19
  === 0.9.9 / 2009-01-04
6
20
 
data/README.txt CHANGED
@@ -1,7 +1,6 @@
1
1
  = dm-tags
2
2
 
3
- http://dm-tags.rubyforge.org/
4
- http://github.com/bobby/dm-tags/
3
+ http://github.com/datamapper/dm-more/tree/master
5
4
 
6
5
  == Description
7
6
 
@@ -61,6 +60,14 @@ This package brings tagging to DataMapper. It is inspired by Acts As Taggable O
61
60
  MyModel.tagged_with('test', :on => 'tags') #=> [#<MyModel id=1>]
62
61
  MyModel.tagged_with('test', :on => 'skills') #=> [#<MyModel id=2>]
63
62
 
63
+
64
+ #Helper methods for text fields
65
+ model.tag_collection = "tag1, tag2, tag3"
66
+ model.save
67
+ model.tag_collection => "tag1, tag2, tag3"
68
+ model.tags
69
+ #=> [#<Tag id=1 name="tag1">, #<Tag id=2 name="tag2">, #<Tag id=3 name="tag3">]
70
+
64
71
  # Traditional 'tags only' tagging
65
72
 
66
73
  class TagsOnly
@@ -86,7 +93,7 @@ This package brings tagging to DataMapper. It is inspired by Acts As Taggable O
86
93
 
87
94
  == Installation
88
95
 
89
- git clone http://github.com/bobby/dm-tags
96
+ git clone http://github.com/datamapper/dm-more/tree/master
90
97
  cd dm-tags
91
98
  rake install
92
99
 
data/Rakefile CHANGED
@@ -12,7 +12,7 @@ AUTHOR = 'Bobby Calderwood'
12
12
  EMAIL = 'bobby_calderwood [a] me [d] com'
13
13
  GEM_NAME = 'dm-tags'
14
14
  GEM_VERSION = DataMapper::Tags::VERSION
15
- GEM_DEPENDENCIES = [['dm-core', "~>#{GEM_VERSION}"], ['dm-validations', "~>#{GEM_VERSION}"]]
15
+ GEM_DEPENDENCIES = [['dm-core', GEM_VERSION], ['dm-validations', GEM_VERSION]]
16
16
  GEM_CLEAN = %w[ log pkg coverage ]
17
17
  GEM_EXTRAS = { :has_rdoc => true, :extra_rdoc_files => %w[ README.txt LICENSE TODO History.txt ] }
18
18
 
@@ -1,6 +1,6 @@
1
1
  require 'rubygems'
2
2
 
3
- gem 'dm-core', '~>0.9.10'
3
+ gem 'dm-core', '0.9.11'
4
4
  require 'dm-core'
5
5
 
6
6
  module DataMapper
@@ -22,10 +22,10 @@ module DataMapper
22
22
  def tagged_with(string, options = {})
23
23
  tag = Tag.first(:name => string)
24
24
  conditions = {}
25
- conditions[:tag_id] = tag.id
26
- conditions[:tag_context] = options[:on] if options.has_key?(:on)
27
- conditions[:taggable_type] = self.to_s
28
- Tagging.all(conditions).map { |tagging| tagging.taggable }
25
+ conditions['taggings.tag_id'] = tag.id
26
+ conditions['taggings.tag_context'] = options.delete(:on) if options[:on]
27
+ conditions.merge!(options)
28
+ all(conditions)
29
29
  end
30
30
 
31
31
  def taggable?
@@ -38,6 +38,19 @@ module DataMapper
38
38
  associations.flatten!
39
39
  associations.uniq!
40
40
 
41
+ class_eval do
42
+ has n, :taggings, :class_name => "Tagging", :child_key => [:taggable_id],
43
+ :taggable_type => self.to_s
44
+
45
+ before :destroy, :destroy_taggings unless respond_to?(:destroy_taggings)
46
+
47
+ def destroy_taggings
48
+ taggings.destroy!
49
+ end unless respond_to?(:destroy_taggings)
50
+
51
+ private :taggings, :taggings=, :destroy_taggings
52
+ end
53
+
41
54
  self.extend(DataMapper::Tags::SingletonMethods)
42
55
 
43
56
  associations.each do |association|
@@ -45,7 +58,7 @@ module DataMapper
45
58
  singular = association.singular
46
59
 
47
60
  class_eval <<-RUBY
48
- property :frozen_#{singular}_list, String
61
+ property :frozen_#{singular}_list, Text
49
62
 
50
63
  has n, :#{singular}_taggings, :class_name => "Tagging", :child_key => [:taggable_id], :taggable_type => self.to_s, :tag_context => "#{association}"
51
64
 
@@ -84,6 +97,29 @@ module DataMapper
84
97
 
85
98
  self.frozen_#{singular}_list = #{association}.map { |tag| tag.name }.join(',')
86
99
  end
100
+
101
+ ##
102
+ # Helper methods to make setting tags easier
103
+ # FIXME: figure out why calling #{singular}_list=(string) won't work
104
+ def #{singular}_collection=(string)
105
+ @#{singular}_list = string.to_s.split(',').map { |name| name.gsub(/[^\\w\\s_-]/i, '').strip }.uniq.sort
106
+ end
107
+
108
+ ##
109
+ # Helper methods to make setting tags easier
110
+ #
111
+ def #{singular}_collection
112
+ #{association}.map { |tag| tag.name }.join(', ')
113
+ end
114
+
115
+ ##
116
+ # Like tag_collection= except it only add's tags
117
+ #
118
+ def add_#{singular}(string)
119
+ tag_array = string.to_s.split(',').map { |name| name.gsub(/[^\\w\\s_-]/i, '').strip }.uniq.sort
120
+ @#{singular}_list = (tag_array + #{singular}_list)
121
+ end
122
+
87
123
  RUBY
88
124
  end
89
125
  end
@@ -9,7 +9,11 @@ class Tagging
9
9
 
10
10
  belongs_to :tag
11
11
 
12
+ if respond_to?(:validates_present)
13
+ validates_present :taggable_type, :taggable_id
14
+ end
15
+
12
16
  def taggable
13
- eval("#{taggable_type}.get!(#{taggable_id})") if taggable_type and taggable_id
17
+ Object.const_get(taggable_type).send(:get!, taggable_id)
14
18
  end
15
19
  end
@@ -1,5 +1,5 @@
1
1
  module DataMapper
2
2
  class Tags
3
- VERSION = '0.9.10'
3
+ VERSION = '0.9.11'
4
4
  end
5
5
  end
@@ -20,4 +20,17 @@ describe Tag do
20
20
  @tag.name = "Meme"
21
21
  @tag.should be_valid
22
22
  end
23
+
24
+ it "should list taggables for a tag" do
25
+ tag = Tag.create!(:name => 'tag1')
26
+ taggable1 = TaggedModel.new
27
+ taggable2 = TaggedModel.new
28
+ taggable3 = TaggedModel.new
29
+ taggable1.tag_list = "tag1"
30
+ taggable1.save
31
+ taggable2.tag_list = "tag1"
32
+ taggable2.save
33
+ tag.taggables.should == [taggable1, taggable2]
34
+ tag.taggables.include?(taggable3).should be_false
35
+ end
23
36
  end
@@ -51,6 +51,30 @@ describe "Taggable" do
51
51
  @taggable.skills.sort_by{|skill| skill.id}.should_not == [tag3, Tag.first(:name => 'tag4')]
52
52
  end
53
53
 
54
+ it "should set tags with a string, and return a string (form helpers)" do
55
+ @taggable = TaggedModel.new
56
+ tags_string = "tag-a, tag-b, tag-c"
57
+ @taggable.tag_collection = tags_string
58
+ @taggable.save
59
+ @taggable.tag_collection.should == tags_string
60
+ @taggable.tags.size.should == 3
61
+ end
62
+
63
+ it "should be able to add tags and not overwrite old tags" do
64
+ @taggable = TaggedModel.new
65
+ @taggable.add_tag("tag-1")
66
+ @taggable.save
67
+ @taggable.tags.size.should == 1
68
+ @taggable.add_tag("tag-2, tag-3")
69
+ @taggable.save
70
+ @taggable.tags.size.should == 3
71
+ @taggable.add_tag("tag-4")
72
+ @taggable.tag_list.include?("tag-4").should be_true
73
+ @taggable.tag_list.include?("tag-1").should be_true
74
+ @taggable.save
75
+ @taggable.tags.size.should == 4
76
+ end
77
+
54
78
  describe ".tagged_with" do
55
79
  it "should have a class method .tagged_with" do
56
80
  DefaultTaggedModel.should respond_to(:tagged_with)
@@ -79,6 +103,18 @@ describe "Taggable" do
79
103
  end
80
104
  end
81
105
 
106
+ it "should allow extra conditions for the query" do
107
+ taggable1 = TaggedModel.new
108
+ taggable2 = TaggedModel.new
109
+ taggable1.tag_list = 'tag1, tag2, tag3'
110
+ taggable2.skill_list = 'tag1, skill4'
111
+ taggable1.save
112
+ taggable2.save
113
+ TaggedModel.tagged_with('tag1').should == [taggable1, taggable2]
114
+ TaggedModel.tagged_with('tag1', :id => taggable1.id).should == [taggable1]
115
+ end
116
+
117
+
82
118
  it "should have a class method .taggable? which returns true if tagging is defined, and false otherwise" do
83
119
  UntaggedModel.taggable?.should be_false
84
120
  TaggedModel.taggable?.should be_true
@@ -90,4 +126,14 @@ describe "Taggable" do
90
126
  TaggedModel.new.taggable?.should == TaggedModel.taggable?
91
127
  TaggedModel.new.taggable?.should be_true
92
128
  end
129
+
130
+ it 'should destroy associated taggings when destroyed' do
131
+ taggable = TaggedModel.new
132
+ taggable.tag_list = 'tag1, tag2, tag3'
133
+ taggable.save
134
+ TaggedModel.tagged_with('tag1').should == [taggable]
135
+ taggable.destroy
136
+ TaggedModel.tagged_with('tag1').should == []
137
+ end
138
+
93
139
  end
@@ -6,6 +6,7 @@ include DataMapper::Tags
6
6
  describe Tagging do
7
7
  before do
8
8
  @tagging = Tagging.new
9
+ @tagged_model =TaggedModel.create
9
10
  end
10
11
 
11
12
  it "should be a model which includes DataMapper::Resource" do
@@ -18,8 +19,6 @@ describe Tagging do
18
19
  @tagging.attributes.should have_key(:tag_id)
19
20
  @tagging.attributes.should have_key(:taggable_id)
20
21
  @tagging.attributes.should have_key(:taggable_type)
21
- # @tagging.attributes.should have_key(:tagger_id)
22
- # @tagging.attributes.should have_key(:tagger_type)
23
22
  @tagging.attributes.should have_key(:tag_context)
24
23
  end
25
24
 
@@ -42,10 +41,8 @@ describe Tagging do
42
41
 
43
42
  it "should have a method Tagging#taggable which returns the associated taggable instance" do
44
43
  @tagging.should respond_to(:taggable)
45
- @tagging.taggable.should_not be
46
- @tagging.taggable_id = 11111
47
- @tagging.taggable_type = "TaggedModel"
48
- TaggedModel.should_receive(:get!).with(11111)
49
- @tagging.taggable
44
+ @tagging.taggable_id = @tagged_model.id
45
+ @tagging.taggable_type = @tagged_model.class.to_s
46
+ @tagging.taggable.should == @tagged_model
50
47
  end
51
48
  end
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'pathname'
2
2
  require 'rubygems'
3
3
 
4
- gem 'dm-core', '~>0.9.8'
4
+ gem 'dm-core', '0.9.11'
5
5
  require 'dm-core'
6
6
 
7
7
  ROOT = Pathname(__FILE__).dirname.parent.expand_path
data/tasks/spec.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  begin
2
- gem 'rspec', '~>1.1.11'
2
+ gem 'rspec', '~>1.2'
3
3
  require 'spec'
4
4
  require 'spec/rake/spectask'
5
5
 
@@ -14,6 +14,7 @@ begin
14
14
  gem 'rcov', '~>0.8'
15
15
  t.rcov = JRUBY ? false : (ENV.has_key?('NO_RCOV') ? ENV['NO_RCOV'] != 'true' : true)
16
16
  t.rcov_opts << '--exclude' << 'spec'
17
+ t.rcov_opts << '--exclude' << 'dm-validations'
17
18
  t.rcov_opts << '--text-summary'
18
19
  t.rcov_opts << '--sort' << 'coverage' << '--sort-reverse'
19
20
  rescue LoadError
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dm-tags
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.10
4
+ version: 0.9.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bobby Calderwood
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-01-19 00:00:00 -08:00
12
+ date: 2009-03-29 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -18,9 +18,9 @@ dependencies:
18
18
  version_requirement:
19
19
  version_requirements: !ruby/object:Gem::Requirement
20
20
  requirements:
21
- - - ~>
21
+ - - "="
22
22
  - !ruby/object:Gem::Version
23
- version: 0.9.10
23
+ version: 0.9.11
24
24
  version:
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: dm-validations
@@ -28,9 +28,9 @@ dependencies:
28
28
  version_requirement:
29
29
  version_requirements: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "="
32
32
  - !ruby/object:Gem::Version
33
- version: 0.9.10
33
+ version: 0.9.11
34
34
  version:
35
35
  description: This package brings tagging to DataMapper. It is inspired by Acts As Taggable On by Michael Bleigh, github's mbleigh. Props to him for the contextual tagging based on Acts As Taggable on Steroids.
36
36
  email: