acts-as-taggable-on 1.0.7 → 1.1.0

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 CHANGED
@@ -1,3 +1,7 @@
1
+ == 2009-12-02
2
+
3
+ * PostgreSQL is now supported (via morgoth)
4
+
1
5
  == 2008-07-17
2
6
 
3
7
  * Can now use a named_scope to find tags!
data/README.rdoc ADDED
@@ -0,0 +1,199 @@
1
+ = ActsAsTaggableOn
2
+
3
+ This plugin was originally based on Acts as Taggable on Steroids by Jonathan Viney.
4
+ It has evolved substantially since that point, but all credit goes to him for the
5
+ initial tagging functionality that so many people have used.
6
+
7
+ For instance, in a social network, a user might have tags that are called skills,
8
+ interests, sports, and more. There is no real way to differentiate between tags and
9
+ so an implementation of this type is not possible with acts as taggable on steroids.
10
+
11
+ Enter Acts as Taggable On. Rather than tying functionality to a specific keyword
12
+ (namely "tags"), acts as taggable on allows you to specify an arbitrary number of
13
+ tag "contexts" that can be used locally or in combination in the same way steroids
14
+ was used.
15
+
16
+ == Installation
17
+
18
+ === Plugin
19
+
20
+ Acts As Taggable On is available both as a gem and as a traditional plugin. For the
21
+ traditional plugin you can install like so (Rails 2.1 or later):
22
+
23
+ script/plugin install git://github.com/mbleigh/acts-as-taggable-on.git
24
+
25
+ === GemPlugin
26
+
27
+ Acts As Taggable On is also available as a gem plugin using Rails 2.1's gem dependencies.
28
+ To install the gem, add this to your config/environment.rb:
29
+
30
+ config.gem "acts-as-taggable-on", :source => "http://gemcutter.org"
31
+
32
+ After that, you can run "rake gems:install" to install the gem if you don't already have it.
33
+
34
+ === Post Installation (Rails)
35
+
36
+ 1. script/generate acts_as_taggable_on_migration
37
+ 2. rake db:migrate
38
+
39
+ === Testing
40
+
41
+ Acts As Taggable On uses RSpec for its test coverage. Inside the plugin
42
+ directory, you can run the specs with:
43
+
44
+ rake spec
45
+
46
+ If you already have RSpec on your application, the specs will run while using:
47
+
48
+ rake spec:plugins
49
+
50
+
51
+ == Usage
52
+
53
+ class User < ActiveRecord::Base
54
+ acts_as_taggable_on :tags, :skills, :interests
55
+ end
56
+
57
+ @user = User.new(:name => "Bobby")
58
+ @user.tag_list = "awesome, slick, hefty" # this should be familiar
59
+ @user.skill_list = "joking, clowning, boxing" # but you can do it for any context!
60
+ @user.skill_list # => ["joking","clowning","boxing"] as TagList
61
+ @user.save
62
+
63
+ @user.tags # => [<Tag name:"awesome">,<Tag name:"slick">,<Tag name:"hefty">]
64
+ @user.skills # => [<Tag name:"joking">,<Tag name:"clowning">,<Tag name:"boxing">]
65
+
66
+ # The old way
67
+ User.find_tagged_with("awesome", :on => :tags) # => [@user]
68
+ User.find_tagged_with("awesome", :on => :skills) # => []
69
+
70
+ # The better way (utilizes named_scope)
71
+ User.tagged_with("awesome", :on => :tags) # => [@user]
72
+ User.tagged_with("awesome", :on => :skills) # => []
73
+
74
+ @frankie = User.create(:name => "Frankie", :skill_list => "joking, flying, eating")
75
+ User.skill_counts # => [<Tag name="joking" count=2>,<Tag name="clowning" count=1>...]
76
+ @frankie.skill_counts
77
+
78
+ === Finding Tagged Objects
79
+
80
+ Acts As Taggable On utilizes Rails 2.1's named_scope to create an association
81
+ for tags. This way you can mix and match to filter down your results, and it
82
+ also improves compatibility with the will_paginate gem:
83
+
84
+ class User < ActiveRecord::Base
85
+ acts_as_taggable_on :tags
86
+ named_scope :by_join_date, :order => "created_at DESC"
87
+ end
88
+
89
+ User.tagged_with("awesome").by_date
90
+ User.tagged_with("awesome").by_date.paginate(:page => params[:page], :per_page => 20)
91
+
92
+ === Relationships
93
+
94
+ You can find objects of the same type based on similar tags on certain contexts.
95
+ Also, objects will be returned in descending order based on the total number of
96
+ matched tags.
97
+
98
+ @bobby = User.find_by_name("Bobby")
99
+ @bobby.skill_list # => ["jogging", "diving"]
100
+
101
+ @frankie = User.find_by_name("Frankie")
102
+ @frankie.skill_list # => ["hacking"]
103
+
104
+ @tom = User.find_by_name("Tom")
105
+ @tom.skill_list # => ["hacking", "jogging", "diving"]
106
+
107
+ @tom.find_related_skills # => [<User name="Bobby">,<User name="Frankie">]
108
+ @bobby.find_related_skills # => [<User name="Tom">]
109
+ @frankie.find_related_skills # => [<User name="Tom">]
110
+
111
+ === Dynamic Tag Contexts
112
+
113
+ In addition to the generated tag contexts in the definition, it is also possible
114
+ to allow for dynamic tag contexts (this could be user generated tag contexts!)
115
+
116
+ @user = User.new(:name => "Bobby")
117
+ @user.set_tag_list_on(:customs, "same, as, tag, list")
118
+ @user.tag_list_on(:customs) # => ["same","as","tag","list"]
119
+ @user.save
120
+ @user.tags_on(:customs) # => [<Tag name='same'>,...]
121
+ @user.tag_counts_on(:customs)
122
+ User.find_tagged_with("same", :on => :customs) # => [@user]
123
+
124
+ === Tag Ownership
125
+
126
+ Tags can have owners:
127
+
128
+ class User < ActiveRecord::Base
129
+ acts_as_tagger
130
+ end
131
+
132
+ class Photo < ActiveRecord::Base
133
+ acts_as_taggable_on :locations
134
+ end
135
+
136
+ @some_user.tag(@some_photo, :with => "paris, normandy", :on => :locations)
137
+ @some_user.owned_taggings
138
+ @some_user.owned_tags
139
+ @some_photo.locations_from(@some_user)
140
+
141
+ === Tag cloud calculations
142
+
143
+ To construct tag clouds, the frequency of each tag needs to be calculated.
144
+ Because we specified +acts_as_taggable_on+ on the <tt>User</tt> class, we can
145
+ get a calculation of all the tag counts by using <tt>User.tag_counts_on(:customs)</tt>. But what if we wanted a tag count for
146
+ an single user's posts? To achieve this we call tag_counts on the association:
147
+
148
+ User.find(:first).posts.tag_counts_on(:tags)
149
+
150
+ A helper is included to assist with generating tag clouds.
151
+
152
+ Here is an example that generates a tag cloud.
153
+
154
+ Helper:
155
+
156
+ module PostsHelper
157
+ include TagsHelper
158
+ end
159
+
160
+ Controller:
161
+
162
+ class PostController < ApplicationController
163
+ def tag_cloud
164
+ @tags = Post.tag_counts_on(:tags)
165
+ end
166
+ end
167
+
168
+ View:
169
+
170
+ <% tag_cloud(@tags, %w(css1 css2 css3 css4)) do |tag, css_class| %>
171
+ <%= link_to tag.name, { :action => :tag, :id => tag.name }, :class => css_class %>
172
+ <% end %>
173
+
174
+ CSS:
175
+
176
+ .css1 { font-size: 1.0em; }
177
+ .css2 { font-size: 1.2em; }
178
+ .css3 { font-size: 1.4em; }
179
+ .css4 { font-size: 1.6em; }
180
+
181
+ == Contributors
182
+
183
+ * TomEric (i76) - Maintainer
184
+ * Michael Bleigh - Original Author
185
+ * Brendan Lim - Related Objects
186
+ * Pradeep Elankumaran - Taggers
187
+ * Sinclair Bain - Patch King
188
+
189
+ == Patch Contributors
190
+
191
+ * tristanzdunn - Related objects of other classes
192
+ * azabaj - Fixed migrate down
193
+ * Peter Cooper - named_scope fix
194
+ * slainer68 - STI fix
195
+ * harrylove - migration instructions and fix-ups
196
+ * lawrencepit - cached tag work
197
+ * sobrinho - fixed tag_cloud helper
198
+
199
+ Copyright (c) 2007-2009 Michael Bleigh (http://mbleigh.com/) and Intridea Inc. (http://intridea.com/), released under the MIT license
data/Rakefile CHANGED
@@ -9,7 +9,7 @@ begin
9
9
  gemspec.email = "michael@intridea.com"
10
10
  gemspec.homepage = "http://github.com/mbleigh/acts-as-taggable-on"
11
11
  gemspec.authors = ["Michael Bleigh"]
12
- gemspec.files = FileList["[A-Z]*", "{lib,spec,rails}/**/*"] - FileList["**/*.log"]
12
+ gemspec.files = FileList["[A-Z]*", "{generators,lib,spec,rails}/**/*"] - FileList["**/*.log"]
13
13
  end
14
14
  Jeweler::GemcutterTasks.new
15
15
  rescue LoadError
@@ -21,3 +21,9 @@ task :default => :spec
21
21
  Spec::Rake::SpecTask.new do |t|
22
22
  t.spec_files = FileList["spec/**/*_spec.rb"]
23
23
  end
24
+
25
+ Spec::Rake::SpecTask.new('rcov') do |t|
26
+ t.spec_files = FileList["spec/**/*_spec.rb"]
27
+ t.rcov = true
28
+ t.rcov_opts = ['--exclude', 'spec']
29
+ end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.7
1
+ 1.1.0
@@ -0,0 +1,7 @@
1
+ class ActsAsTaggableOnMigrationGenerator < Rails::Generator::Base
2
+ def manifest
3
+ record do |m|
4
+ m.migration_template 'migration.rb', 'db/migrate', :migration_file_name => "acts_as_taggable_on_migration"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,29 @@
1
+ class ActsAsTaggableOnMigration < 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
+ t.column :tagger_id, :integer
11
+ t.column :tagger_type, :string
12
+
13
+ # You should make sure that the column created is
14
+ # long enough to store the required class names.
15
+ t.column :taggable_type, :string
16
+ t.column :context, :string
17
+
18
+ t.column :created_at, :datetime
19
+ end
20
+
21
+ add_index :taggings, :tag_id
22
+ add_index :taggings, [:taggable_id, :taggable_type, :context]
23
+ end
24
+
25
+ def self.down
26
+ drop_table :taggings
27
+ drop_table :tags
28
+ end
29
+ end
@@ -1,3 +1,4 @@
1
+ require 'acts_as_taggable_on/group_helper'
1
2
  require 'acts_as_taggable_on/acts_as_taggable_on'
2
3
  require 'acts_as_taggable_on/acts_as_tagger'
3
4
  require 'acts_as_taggable_on/tag'