dm-tags 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,9 @@
1
+ == 0.0.1 2008-07-29
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
5
+
6
+ == 0.0.2 2008-07-30
7
+
8
+ * 1 major enhancement:
9
+ * Added contextual finding to Model.tagged_with
data/License.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Bobby Calderwood
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest.txt ADDED
@@ -0,0 +1,20 @@
1
+ History.txt
2
+ License.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ lib/dm-tags.rb
7
+ lib/dm-tags/dm_tags.rb
8
+ lib/dm-tags/tag.rb
9
+ lib/dm-tags/tagging.rb
10
+ lib/dm-tags/version.rb
11
+ setup.rb
12
+ spec/classes.rb
13
+ spec/dm-setup.rb
14
+ spec/dm-tags/dm_tags_spec.rb
15
+ spec/dm-tags/tag_spec.rb
16
+ spec/dm-tags/taggable_spec.rb
17
+ spec/dm-tags/tagging_spec.rb
18
+ spec/spec.opts
19
+ spec/spec_helper.rb
20
+ tasks/rspec.rake
data/README.txt ADDED
@@ -0,0 +1,113 @@
1
+ = dm-tags
2
+
3
+ http://dm-tags.rubyforge.org/
4
+ http://github.com/bobby/dm-tags/
5
+
6
+ == Description
7
+
8
+ 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.
9
+
10
+ == Features and Problems
11
+
12
+ === Features
13
+
14
+ * Contextual tagging using Model.has_tags_on (see below for usage)
15
+ * Traditional 'tags-only' tagging using Model.has_tags
16
+
17
+ === Problems
18
+
19
+ * None known yet, but this is very alpha software. Sorry if it misbehaves. Please send me a github message if you find a bug.
20
+
21
+ == Synopsis
22
+
23
+ require 'rubygems'
24
+ require 'dm-core'
25
+ require 'dm-tags'
26
+
27
+ DataMapper.setup(:default, "sqlite3::memory:")
28
+
29
+ class MyModel
30
+ include DataMapper::Resource
31
+ property :id, Integer, :serial => true
32
+ has_tags_on :tags, :skills
33
+ end
34
+
35
+ DataMapper.auto_migrate!
36
+
37
+ # Contextual tagging
38
+ MyModel.taggable? #=> true
39
+ MyModel.new.taggable? #=> true
40
+
41
+ model = MyModel.new
42
+ model.tag_list = 'test, me out, please '
43
+ model.tag_list #=> ['me out', 'please', 'test'] # Sanitized and alphabetized
44
+ model.save #=> true
45
+ model.tags #=> [#<Tag id=1 name="me out">, #<Tag id=2 name="please">, #<Tag id=3 name="test">]
46
+ model.tag_list = 'test, again'
47
+ model.save #=> true
48
+ model.tags #=> [#<Tag id=3 name="test">, #<Tag id=4 name="again">] # Checks for existing tags
49
+ Tag.all #=> [#<Tag id=1 name="me out">, #<Tag id=2 name="please">, #<Tag id=3 name="test">, #<Tag id=4 name="again">]
50
+ another = MyModel.new
51
+ another.skill_list = 'test, all, you, like'
52
+ another.save #=> true
53
+ another.tag_list #=> []
54
+ another.skills
55
+ #=> [#<Tag id=5 name="all">, #<Tag id=6 name="like">, #<Tag id=3 name="test">, #<Tag id=7 name="you">]
56
+
57
+ MyModel.tagged_with('test') #=> [#<MyModel id=1>, #<MyModel id=2>]
58
+ MyModel.tagged_with('test', :on => 'tags') #=> [#<MyModel id=1>]
59
+ MyModel.tagged_with('test', :on => 'skills') #=> [#<MyModel id=2>]
60
+
61
+ # Traditional 'tags only' tagging
62
+
63
+ class TagsOnly
64
+ include DataMapper::Resource
65
+ property :id, Integer, :serial => true
66
+ has_tags
67
+ end
68
+
69
+ TagsOnly.auto_migrate!
70
+
71
+ TagsOnly.taggable? #=> true
72
+ TagsOnly.new.taggable? #=> true
73
+
74
+ tags_only = TagsOnly.new
75
+ tags_only.tag_list = 'tags, only'
76
+ tags_only.tag_list #=> ['only', 'tags']
77
+ tags_only.save #=> true
78
+ tags_only.tags #=> [#<Tag id=8 name="only">, #<Tag id=9 name="tags">]
79
+
80
+ == Requirements
81
+
82
+ * DataMapper (dm-core)
83
+
84
+ == Installation
85
+
86
+ git clone http://github.com/bobby/dm-tags
87
+ cd dm-tags
88
+ rake install
89
+
90
+ == License
91
+
92
+ (The MIT License)
93
+
94
+ Copyright (c) 2008 Bobby Calderwood
95
+
96
+ Permission is hereby granted, free of charge, to any person obtaining
97
+ a copy of this software and associated documentation files (the
98
+ 'Software'), to deal in the Software without restriction, including
99
+ without limitation the rights to use, copy, modify, merge, publish,
100
+ distribute, sublicense, and/or sell copies of the Software, and to
101
+ permit persons to whom the Software is furnished to do so, subject to
102
+ the following conditions:
103
+
104
+ The above copyright notice and this permission notice shall be
105
+ included in all copies or substantial portions of the Software.
106
+
107
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
108
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
109
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
110
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
111
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
112
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
113
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ require 'config/requirements'
2
+ require 'config/hoe' # setup Hoe + all gem configuration
3
+
4
+ Dir['tasks/**/*.rake'].each { |rake| load rake }
@@ -0,0 +1,97 @@
1
+ require 'dm-core'
2
+ module DataMapper
3
+ module Resource
4
+ class << self
5
+ alias_method :old_included, :included
6
+ def included(receiver)
7
+ old_included(receiver)
8
+ receiver.send(:include, DataMapper::Tags)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ module DataMapper
14
+ module Tags
15
+ module ClassMethods
16
+ def has_tags_on(*args)
17
+ args.flatten!
18
+ args.uniq!
19
+
20
+ self.extend(DataMapper::Tags::SingletonMethods)
21
+
22
+ args.map{|arg| arg.to_sym}.each do |arg|
23
+ class_eval <<-RUBY
24
+ property :frozen_#{arg.to_s.singular}_list, String
25
+ has n, :#{arg.to_s.singular}_taggings, :class_name => "Tagging", :child_key => [:taggable_id],
26
+ :taggable_type => self.to_s, :tag_context => "#{arg}"
27
+ before :save, :update_#{arg}
28
+
29
+ def #{arg}
30
+ #{arg.to_s.singular}_taggings.map{|tagging| tagging.tag}
31
+ end
32
+
33
+ def #{arg.to_s.singular}_list
34
+ @#{arg.to_s.singular}_list || #{arg}.map{|#{arg.to_s.singular}| #{arg.to_s.singular}.name}.sort
35
+ end
36
+
37
+ def #{arg.to_s.singular}_list=(string)
38
+ @#{arg.to_s.singular}_list = string.to_s.split(",").map{|name| name.gsub(/[^\\w\\s_-]/i,"").strip}.uniq.sort
39
+ end
40
+
41
+ def update_#{arg}
42
+ return if #{arg.to_s.singular}_list.empty?
43
+ deleted_#{arg} = frozen_#{arg.to_s.singular}_list.to_s.split(',') - #{arg.to_s.singular}_list
44
+ deleted_#{arg}.each do |name|
45
+ tag = Tag.first(:name => name)
46
+ tagging = #{arg.to_s.singular}_taggings.first(:tag_id => tag.id)
47
+ tagging.destroy
48
+ #{arg.to_s.singular}_taggings.reload
49
+ end
50
+ #{arg.to_s.singular}_list.each do |name|
51
+ tag = Tag.first(:name => name)
52
+ next if #{arg}.to_a.include?(tag)
53
+ tag = Tag.create!(:name => name) unless tag
54
+ #{arg.to_s.singular}_taggings << Tagging.new(:tag => tag, :taggable_type => self.class.to_s, :tag_context => "#{arg}")
55
+ end
56
+ self.frozen_#{arg.to_s.singular}_list = #{arg}.map{|#{arg.to_s.singular}| #{arg.to_s.singular}.name}.sort.join(',')
57
+ end
58
+ RUBY
59
+ end
60
+ end
61
+
62
+ def has_tags(*args)
63
+ has_tags_on :tags
64
+ end
65
+
66
+ def taggable?
67
+ false
68
+ end
69
+ end
70
+
71
+ module SingletonMethods
72
+ # Class Methods
73
+ def tagged_with(string, options = {})
74
+ tag = Tag.first(:name => string)
75
+ conditions = {}
76
+ conditions[:tag_id] = tag.id
77
+ conditions[:tag_context] = options[:on] if options[:on]
78
+ Tagging.all(conditions).map{|tagging| tagging.taggable}
79
+ end
80
+
81
+ def taggable?
82
+ true
83
+ end
84
+ end
85
+
86
+ module InstanceMethods
87
+ def taggable?
88
+ self.class.taggable?
89
+ end
90
+ end
91
+
92
+ def self.included(receiver)
93
+ receiver.send(:include, InstanceMethods)
94
+ receiver.extend(ClassMethods)
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,11 @@
1
+ class Tag
2
+ include DataMapper::Resource
3
+ property :id, Integer, :serial => true
4
+ property :name, String, :nullable => false, :unique => true
5
+
6
+ has n, :taggings
7
+
8
+ def taggables
9
+ taggings.map{|tagging| tagging.taggable}
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ class Tagging
2
+ include DataMapper::Resource
3
+ property :id, Integer, :serial => true
4
+ property :tag_id, Integer, :nullable => false
5
+ property :taggable_id, Integer, :nullable => false
6
+ property :taggable_type, String, :nullable => false
7
+ property :tag_context, String, :nullable => false
8
+
9
+ belongs_to :tag
10
+
11
+ def taggable
12
+ eval("#{taggable_type}.get!(#{taggable_id})") if taggable_type and taggable_id
13
+ end
14
+ end
@@ -0,0 +1,10 @@
1
+ require 'dm-core'
2
+ module DataMapper::Tags
3
+ module VERSION #:nodoc:
4
+ MAJOR = 0
5
+ MINOR = 0
6
+ TINY = 2
7
+
8
+ STRING = [MAJOR, MINOR, TINY].join('.')
9
+ end
10
+ end
data/lib/dm-tags.rb ADDED
@@ -0,0 +1,6 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'dm-tags/tagging'
5
+ require 'dm-tags/tag'
6
+ require 'dm-tags/dm_tags'