rotuka-taggable 0.0.1

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/CHANGELOG ADDED
@@ -0,0 +1,167 @@
1
+ [13 March 08]
2
+
3
+ * Added helper methods for will_paginate compatibility (Clinton R. Nixon)
4
+ * Fixed :conditions in tag_counts to accept array to sanitize (Clinton R. Nixon)
5
+
6
+ [07 March 08]
7
+
8
+ * Added support for regexp delimiter (Matt Aimonetti)
9
+
10
+ [30 Jan 08]
11
+
12
+ * Fix Tag.destroy_unused on Rails 2.0.
13
+
14
+ [23 October 2007]
15
+
16
+ * Make find_options_for_tag_counts and find_options_for_tagged_with dup their options.
17
+
18
+ * Apply conditions properly in find_options_for_tag_counts.
19
+
20
+ * Fix tag_cloud when no tags are present.
21
+
22
+ [22 October 2007]
23
+
24
+ * Fix find_tagged_with using :match_all and :include.
25
+
26
+ * Use inner joins instead of left outer joins.
27
+
28
+ [15 October 2007]
29
+
30
+ * Make find_tagged_with correctly apply :conditions
31
+
32
+ * Add Tag.destroy_unused option.
33
+
34
+ [11 October 2007]
35
+
36
+ * Make tag_counts work correctly with STI.
37
+
38
+ [3 October 2007]
39
+
40
+ * Improve documentation.
41
+
42
+ * Fix TagsHelper and test.
43
+
44
+ [2 October 2007]
45
+
46
+ * Remove TagList.parse, use TagList.from instead.
47
+
48
+ * Add :parse option to TagList#new, TagList#add, and TagList#remove.
49
+
50
+ tag_list = TagList.new("One, Two", :parse => true) # ["One", "Two"]
51
+
52
+ tag_list # ["One", "Two"]
53
+ tag_list.add("Three, Four", :parse => true) # ["One", "Two", "Three", "Four"]
54
+
55
+ * Remove TagList#names.
56
+
57
+ [29 September 2007]
58
+
59
+ * Add TagsHelper to assist with generating tag clouds and provide a simple example.
60
+
61
+ [27 September 2007]
62
+
63
+ * Add #tag_counts method to get tag counts for a specific object's tags.
64
+
65
+ * BACKWARDS INCOMPATIBILITY: Rename #find_options_for_tagged_with to #find_options_for_find_tagged_with
66
+
67
+ [17 September 2007]
68
+
69
+ * Fix clearing of cached tag list when all tags removed.
70
+
71
+ [12 September 2007]
72
+
73
+ * Make the TagList class inherit from Array.
74
+
75
+ * Deprecate obsolete TagList#names.
76
+
77
+ [6 September 2007]
78
+
79
+ * Add TagList#include? and TagList#empty?
80
+
81
+ [26 August 2006]
82
+
83
+ * Remove deprecated Tag.delimiter. Use TagList.delimiter instead.
84
+
85
+ [25 August 2007]
86
+
87
+ * Make tag_counts work with has_many :through
88
+
89
+ [23 August 2007]
90
+
91
+ * Make search comparisons case-insensitive across different databases. [Moisés Machado]
92
+
93
+ * Improve compatiblity with STI. [Moisés Machado]
94
+
95
+ [25 July 2007]
96
+
97
+ * Respect custom table names for the Tag and Tagging classes.
98
+
99
+ * Fix the :exclude option for find_tagged_with
100
+
101
+ [17 July 2007]
102
+
103
+ * Make the migration work on edge rails
104
+
105
+ [8 July 2007]
106
+
107
+ * find_options_for_tagged_with should not alter its arguments
108
+
109
+ [1 July 2007]
110
+
111
+ * Fix incorrect tagging when the case of the tag list is changed.
112
+
113
+ * Fix deprecated Tag.delimiter accessor.
114
+
115
+ [23 June 2007]
116
+
117
+ * Add validation to Tag model.
118
+
119
+ * find_options_for_tagged_with should always return a hash.
120
+
121
+ * find_tagged_with passing in no tags should return an empty array.
122
+
123
+ * Improve compatibility with PostgreSQL.
124
+
125
+ [21 June 2007]
126
+
127
+ * Remove extra .rb from generated migration file name.
128
+
129
+ [15 June 2007]
130
+
131
+ * Introduce TagList class.
132
+
133
+ * Various cleanups and improvements.
134
+
135
+ * Use TagList.delimiter now, not Tag.delimiter. Tag.delimiter will be removed at some stage.
136
+
137
+ [11 June 2007]
138
+
139
+ * Restructure the creation of the options for find_tagged_with [Thijs Cadier]
140
+
141
+ * Add an example migration with a generator.
142
+
143
+ * Add caching.
144
+
145
+ * Fix compatibility with Ruby < 1.8.6
146
+
147
+ [23 April 2007]
148
+
149
+ * Make tag_list to respect Tag.delimiter
150
+
151
+ [31 March 2007]
152
+
153
+ * Add Tag.delimiter accessor to change how tags are parsed.
154
+
155
+ * Fix :include => :tags when used with find_tagged_with
156
+
157
+ [7 March 2007]
158
+
159
+ * Fix tag_counts for SQLServer [Brad Young]
160
+
161
+ [21 Feb 2007]
162
+
163
+ * Use scoping instead of TagCountsExtension [Michael Schuerig]
164
+
165
+ [7 Jan 2007]
166
+
167
+ * Add :match_all to find_tagged_with [Michael Sheakoski]
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2006 Jonathan Viney
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/README ADDED
@@ -0,0 +1,146 @@
1
+ = Taggable gem
2
+
3
+ == Instructions
4
+
5
+ This gem is based on acts_as_taggable_on_steroids by Jonathan Viney but includes extras
6
+ such as tests, smarter tag assignment, and tag cloud calculations.
7
+
8
+ == Installation
9
+
10
+ sudo gem install rotuka-taggable --source=http://gems.github.com
11
+
12
+ == Usage
13
+
14
+ In environment.rb add dependencie
15
+ config.gem 'rotuka-taggable', :lib => 'taggable'
16
+
17
+ === Prepare database
18
+
19
+ Generate and apply the migration:
20
+
21
+ ruby script/generate tags
22
+ rake db:migrate
23
+
24
+ === Basic tagging
25
+
26
+ Let's suppose users have many posts and we want those posts to have tags.
27
+ The first step is to add +acts_as_taggable+ to the Post class:
28
+
29
+ class Post < ActiveRecord::Base
30
+ acts_as_taggable
31
+
32
+ belongs_to :user
33
+ end
34
+
35
+ We can now use the tagging methods provided by acts_as_taggable, <tt>#tag_list</tt> and <tt>#tag_list=</tt>. Both these
36
+ methods work like regular attribute accessors.
37
+
38
+ p = Post.find(:first)
39
+ p.tag_list # []
40
+ p.tag_list = "Funny, Silly"
41
+ p.save
42
+ p.tag_list # ["Funny", "Silly"]
43
+
44
+ You can also add or remove arrays of tags.
45
+
46
+ p.tag_list.add("Great", "Awful")
47
+ p.tag_list.remove("Funny")
48
+
49
+ === Finding tagged objects
50
+
51
+ To retrieve objects tagged with a certain tag, use find_tagged_with.
52
+
53
+ Post.find_tagged_with('Funny, Silly')
54
+
55
+ By default, find_tagged_with will find objects that have any of the given tags. To
56
+ find only objects that are tagged with all the given tags, use match_all.
57
+
58
+ Post.find_tagged_with('Funny, Silly', :match_all => true)
59
+
60
+ See <tt>ActiveRecord::Acts::Taggable::InstanceMethods</tt> for more methods and options.
61
+
62
+ === Tag cloud calculations
63
+
64
+ To construct tag clouds, the frequency of each tag needs to be calculated.
65
+ Because we specified +acts_as_taggable+ on the <tt>Post</tt> class, we can
66
+ get a calculation of all the tag counts by using <tt>Post.tag_counts</tt>. But what if we wanted a tag count for
67
+ an single user's posts? To achieve this we call tag_counts on the association:
68
+
69
+ User.find(:first).posts.tag_counts
70
+
71
+ A helper is included to assist with generating tag clouds. Include it in your helper file:
72
+
73
+ module ApplicationHelper
74
+ include TagsHelper
75
+ end
76
+
77
+ Here is an example that generates a tag cloud.
78
+
79
+ Controller:
80
+
81
+ class PostController < ApplicationController
82
+ def tag_cloud
83
+ @tags = Post.tag_counts
84
+ end
85
+ end
86
+
87
+ View:
88
+ <% tag_cloud @tags, %w(css1 css2 css3 css4) do |tag, css_class| %>
89
+ <%= link_to tag.name, { :action => :tag, :id => tag.name }, :class => css_class %>
90
+ <% end %>
91
+
92
+ CSS:
93
+
94
+ .css1 { font-size: 1.0em; }
95
+ .css2 { font-size: 1.2em; }
96
+ .css3 { font-size: 1.4em; }
97
+ .css4 { font-size: 1.6em; }
98
+
99
+ === Caching
100
+
101
+ It is useful to cache the list of tags to reduce the number of queries executed. To do this,
102
+ add a column named <tt>cached_tag_list</tt> to the model which is being tagged. The column should be long enough to hold
103
+ the full tag list and must have a default value of null, not an empty string.
104
+
105
+ class CachePostTagList < ActiveRecord::Migration
106
+ def self.up
107
+ add_column :posts, :cached_tag_list, :string
108
+ end
109
+ end
110
+
111
+ class Post < ActiveRecord::Base
112
+ acts_as_taggable
113
+
114
+ # The caching column defaults to cached_tag_list, but can be changed:
115
+ #
116
+ # set_cached_tag_list_column_name "my_caching_column_name"
117
+ end
118
+
119
+ The details of the caching are handled for you. Just continue to use the tag_list accessor as you normally would.
120
+ Note that the cached tag list will not be updated if you directly create Tagging objects or manually append to the
121
+ <tt>tags</tt> or <tt>taggings</tt> associations. To update the cached tag list you should call <tt>save_cached_tag_list</tt> manually.
122
+
123
+ === Delimiter
124
+
125
+ If you want to change the delimiter used to parse and present tags, set TagList.delimiter.
126
+ For example, to use spaces instead of commas, add the following to config/environment.rb:
127
+
128
+ TagList.delimiter = " "
129
+
130
+ You can also use a regexp as delimiter:
131
+
132
+ TagList.delimiter = /,|;/
133
+
134
+ The above code would parse the string and use ',' and ';' as delimiters.
135
+
136
+ === Unused tags
137
+
138
+ Set Tag.destroy_unused to remove tags when they are no longer being
139
+ used to tag any objects. Defaults to false.
140
+
141
+ Tag.destroy_unused = true
142
+
143
+ === Other
144
+
145
+ Problems, comments, and suggestions all welcome.
146
+ me@rotuka.com
data/Rakefile ADDED
@@ -0,0 +1,22 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the taggable gem.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.pattern = 'test/**/*_test.rb'
12
+ t.verbose = true
13
+ end
14
+
15
+ desc 'Generate documentation for the taggable gem.'
16
+ Rake::RDocTask.new(:rdoc) do |rdoc|
17
+ rdoc.rdoc_dir = 'rdoc'
18
+ rdoc.title = 'Taggable'
19
+ rdoc.options << '--line-numbers' << '--inline-source'
20
+ rdoc.rdoc_files.include('README')
21
+ rdoc.rdoc_files.include('lib/**/*.rb')
22
+ end
@@ -0,0 +1 @@
1
+ script/generate tags
@@ -0,0 +1,14 @@
1
+ class TagsGenerator < Rails::Generator::Base
2
+ def manifest
3
+ record do |m|
4
+ m.migration_template 'migration.rb', 'db/migrate'
5
+ m.file "tag.rb", "app/models/tag.rb"
6
+ m.file "tagging.rb", "app/models/tagging.rb"
7
+ m.file "tags_helper.rb", "app/helpers/tags_helper.rb"
8
+ end
9
+ end
10
+
11
+ def file_name
12
+ "acts_as_taggable_migration"
13
+ end
14
+ end
@@ -0,0 +1,26 @@
1
+ class ActsAsTaggableMigration < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :tags do |t|
4
+ t.column :name, :string
5
+ end
6
+
7
+ create_table :taggings do |t|
8
+ t.column :tag_id, :integer
9
+ t.column :taggable_id, :integer
10
+
11
+ # You should make sure that the column created is
12
+ # long enough to store the required class names.
13
+ t.column :taggable_type, :string
14
+
15
+ t.column :created_at, :datetime
16
+ end
17
+
18
+ add_index :taggings, :tag_id
19
+ add_index :taggings, [:taggable_id, :taggable_type]
20
+ end
21
+
22
+ def self.down
23
+ drop_table :taggings
24
+ drop_table :tags
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ class Tag < ActiveRecord::Base
2
+ has_many :taggings
3
+
4
+ validates_presence_of :name
5
+ validates_uniqueness_of :name
6
+
7
+ cattr_accessor :destroy_unused
8
+ self.destroy_unused = false
9
+
10
+ # LIKE is used for cross-database case-insensitivity
11
+ def self.find_or_create_with_like_by_name(name)
12
+ find(:first, :conditions => ["name LIKE ?", name]) || create(:name => name)
13
+ end
14
+
15
+ def ==(object)
16
+ super || (object.is_a?(Tag) && name == object.name)
17
+ end
18
+
19
+ def to_s
20
+ name
21
+ end
22
+
23
+ def count
24
+ read_attribute(:count).to_i
25
+ end
26
+ end
@@ -0,0 +1,12 @@
1
+ class Tagging < ActiveRecord::Base #:nodoc:
2
+ belongs_to :tag
3
+ belongs_to :taggable, :polymorphic => true
4
+
5
+ def after_destroy
6
+ if Tag.destroy_unused
7
+ if tag.taggings.count.zero?
8
+ tag.destroy
9
+ end
10
+ end
11
+ end
12
+ end