yetanothernguyen-acts-as-taggable-on 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/CHANGELOG +25 -0
  2. data/Gemfile +10 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +221 -0
  5. data/Rakefile +59 -0
  6. data/VERSION +1 -0
  7. data/generators/acts_as_taggable_on_migration/acts_as_taggable_on_migration_generator.rb +7 -0
  8. data/generators/acts_as_taggable_on_migration/templates/migration.rb +29 -0
  9. data/lib/acts-as-taggable-on.rb +30 -0
  10. data/lib/acts_as_taggable_on/acts_as_taggable_on.rb +53 -0
  11. data/lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb +53 -0
  12. data/lib/acts_as_taggable_on/acts_as_taggable_on/collection.rb +139 -0
  13. data/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb +262 -0
  14. data/lib/acts_as_taggable_on/acts_as_taggable_on/ownership.rb +105 -0
  15. data/lib/acts_as_taggable_on/acts_as_taggable_on/related.rb +69 -0
  16. data/lib/acts_as_taggable_on/acts_as_tagger.rb +67 -0
  17. data/lib/acts_as_taggable_on/compatibility/Gemfile +8 -0
  18. data/lib/acts_as_taggable_on/compatibility/active_record_backports.rb +21 -0
  19. data/lib/acts_as_taggable_on/tag.rb +84 -0
  20. data/lib/acts_as_taggable_on/tag_list.rb +96 -0
  21. data/lib/acts_as_taggable_on/tagging.rb +24 -0
  22. data/lib/acts_as_taggable_on/tags_helper.rb +17 -0
  23. data/lib/generators/acts_as_taggable_on/migration/migration_generator.rb +32 -0
  24. data/lib/generators/acts_as_taggable_on/migration/templates/active_record/migration.rb +28 -0
  25. data/rails/init.rb +1 -0
  26. data/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb +268 -0
  27. data/spec/acts_as_taggable_on/acts_as_tagger_spec.rb +114 -0
  28. data/spec/acts_as_taggable_on/tag_list_spec.rb +70 -0
  29. data/spec/acts_as_taggable_on/tag_spec.rb +115 -0
  30. data/spec/acts_as_taggable_on/taggable_spec.rb +343 -0
  31. data/spec/acts_as_taggable_on/tagger_spec.rb +91 -0
  32. data/spec/acts_as_taggable_on/tagging_spec.rb +31 -0
  33. data/spec/acts_as_taggable_on/tags_helper_spec.rb +28 -0
  34. data/spec/bm.rb +52 -0
  35. data/spec/database.yml.sample +17 -0
  36. data/spec/models.rb +31 -0
  37. data/spec/schema.rb +43 -0
  38. data/spec/spec_helper.rb +60 -0
  39. metadata +115 -0
data/CHANGELOG ADDED
@@ -0,0 +1,25 @@
1
+ == 2010-02-17
2
+ * Converted the plugin to be compatible with Rails3
3
+
4
+ == 2009-12-02
5
+
6
+ * PostgreSQL is now supported (via morgoth)
7
+
8
+ == 2008-07-17
9
+
10
+ * Can now use a named_scope to find tags!
11
+
12
+ == 2008-06-23
13
+
14
+ * Can now find related objects of another class (tristanzdunn)
15
+ * Removed extraneous down migration cruft (azabaj)
16
+
17
+ == 2008-06-09
18
+
19
+ * Added support for Single Table Inheritance
20
+ * Adding gemspec and rails/init.rb for gemified plugin
21
+
22
+ == 2007-12-12
23
+
24
+ * Added ability to use dynamic tag contexts
25
+ * Fixed missing migration generator
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source :gemcutter
2
+
3
+ # Rails 3.0
4
+ gem 'rails', '3.0.0.beta3'
5
+ gem 'rspec', '2.0.0.beta.8'
6
+ gem 'sqlite3-ruby', :require => 'sqlite3'
7
+ gem 'mysql'
8
+ gem 'pg'
9
+ gem 'jeweler'
10
+ gem 'rcov'
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2007 Michael Bleigh and Intridea Inc.
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.rdoc ADDED
@@ -0,0 +1,221 @@
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
+ === Rails 2.3.x
19
+
20
+ Acts As Taggable On is tested to work in Rails 2.3.5.
21
+
22
+ ==== Plugin
23
+
24
+ Acts As Taggable On is available both as a gem and as a traditional plugin. For the
25
+ traditional plugin you can install like so:
26
+
27
+ script/plugin install git://github.com/mbleigh/acts-as-taggable-on.git
28
+
29
+ Acts As Taggable On is also available as a gem plugin using Rails 2.1's gem dependencies.
30
+ To install the gem, add this to your config/environment.rb:
31
+
32
+ config.gem "acts-as-taggable-on", :source => "http://gemcutter.org", :version => '2.0.0.rc1'
33
+
34
+ After that, you can run "rake gems:install" to install the gem if you don't already have it.
35
+
36
+ ==== Post Installation
37
+
38
+ 1. script/generate acts_as_taggable_on_migration
39
+ 2. rake db:migrate
40
+
41
+ === Rails 3.0
42
+
43
+ Acts As Taggable On is now useable in Rails 3.0, thanks to the excellent work of Szymon Nowak
44
+ and Jelle Vandebeeck.
45
+
46
+ To use it, add it to your Gemfile:
47
+
48
+ gem 'acts-as-taggable-on'
49
+
50
+ ==== Post Installation
51
+
52
+ 1. rails generate acts_as_taggable_on:migration
53
+ 2. rake db:migrate
54
+
55
+ == Testing
56
+
57
+ Acts As Taggable On uses RSpec for its test coverage. Inside the plugin
58
+ directory, you can run the specs for RoR 3.0.0 with:
59
+
60
+ rake spec
61
+
62
+ If you want to test the plugin for Rails 2.3.x, use:
63
+
64
+ rake rails2.3:spec
65
+
66
+ If you already have RSpec on your application, the specs will run while using:
67
+
68
+ rake spec:plugins
69
+
70
+
71
+ == Usage
72
+
73
+ class User < ActiveRecord::Base
74
+ # Alias for <tt>acts_as_taggable_on :tags</tt>:
75
+ acts_as_taggable
76
+ acts_as_taggable_on :skills, :interests
77
+ end
78
+
79
+ @user = User.new(:name => "Bobby")
80
+ @user.tag_list = "awesome, slick, hefty" # this should be familiar
81
+ @user.skill_list = "joking, clowning, boxing" # but you can do it for any context!
82
+ @user.skill_list # => ["joking","clowning","boxing"] as TagList
83
+ @user.save
84
+
85
+ @user.tags # => [<Tag name:"awesome">,<Tag name:"slick">,<Tag name:"hefty">]
86
+ @user.skills # => [<Tag name:"joking">,<Tag name:"clowning">,<Tag name:"boxing">]
87
+
88
+ @frankie = User.create(:name => "Frankie", :skill_list => "joking, flying, eating")
89
+ User.skill_counts # => [<Tag name="joking" count=2>,<Tag name="clowning" count=1>...]
90
+ @frankie.skill_counts
91
+
92
+ === Finding Tagged Objects
93
+
94
+ Acts As Taggable On utilizes named_scopes to create an association for tags.
95
+ This way you can mix and match to filter down your results, and it also improves
96
+ compatibility with the will_paginate gem:
97
+
98
+ class User < ActiveRecord::Base
99
+ acts_as_taggable_on :tags
100
+ named_scope :by_join_date, :order => "created_at DESC"
101
+ end
102
+
103
+ User.tagged_with("awesome").by_date
104
+ User.tagged_with("awesome").by_date.paginate(:page => params[:page], :per_page => 20)
105
+
106
+ # Find a user with matching all tags, not just one
107
+ User.tagged_with(["awesome", "cool"], :match_all => :true)
108
+
109
+ # Find a user with any of the tags:
110
+ User.tagged_with(["awesome", "cool"], :any => true)
111
+
112
+ === Relationships
113
+
114
+ You can find objects of the same type based on similar tags on certain contexts.
115
+ Also, objects will be returned in descending order based on the total number of
116
+ matched tags.
117
+
118
+ @bobby = User.find_by_name("Bobby")
119
+ @bobby.skill_list # => ["jogging", "diving"]
120
+
121
+ @frankie = User.find_by_name("Frankie")
122
+ @frankie.skill_list # => ["hacking"]
123
+
124
+ @tom = User.find_by_name("Tom")
125
+ @tom.skill_list # => ["hacking", "jogging", "diving"]
126
+
127
+ @tom.find_related_skills # => [<User name="Bobby">,<User name="Frankie">]
128
+ @bobby.find_related_skills # => [<User name="Tom">]
129
+ @frankie.find_related_skills # => [<User name="Tom">]
130
+
131
+ === Dynamic Tag Contexts
132
+
133
+ In addition to the generated tag contexts in the definition, it is also possible
134
+ to allow for dynamic tag contexts (this could be user generated tag contexts!)
135
+
136
+ @user = User.new(:name => "Bobby")
137
+ @user.set_tag_list_on(:customs, "same, as, tag, list")
138
+ @user.tag_list_on(:customs) # => ["same","as","tag","list"]
139
+ @user.save
140
+ @user.tags_on(:customs) # => [<Tag name='same'>,...]
141
+ @user.tag_counts_on(:customs)
142
+ User.tagged_with("same", :on => :customs) # => [@user]
143
+
144
+ === Tag Ownership
145
+
146
+ Tags can have owners:
147
+
148
+ class User < ActiveRecord::Base
149
+ acts_as_tagger
150
+ end
151
+
152
+ class Photo < ActiveRecord::Base
153
+ acts_as_taggable_on :locations
154
+ end
155
+
156
+ @some_user.tag(@some_photo, :with => "paris, normandy", :on => :locations)
157
+ @some_user.owned_taggings
158
+ @some_user.owned_tags
159
+ @some_photo.locations_from(@some_user)
160
+
161
+ === Tag cloud calculations
162
+
163
+ To construct tag clouds, the frequency of each tag needs to be calculated.
164
+ Because we specified +acts_as_taggable_on+ on the <tt>User</tt> class, we can
165
+ 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
166
+ an single user's posts? To achieve this we call tag_counts on the association:
167
+
168
+ User.find(:first).posts.tag_counts_on(:tags)
169
+
170
+ A helper is included to assist with generating tag clouds.
171
+
172
+ Here is an example that generates a tag cloud.
173
+
174
+ Helper:
175
+
176
+ module PostsHelper
177
+ include ActsAsTaggableOn::TagsHelper
178
+ end
179
+
180
+ Controller:
181
+
182
+ class PostController < ApplicationController
183
+ def tag_cloud
184
+ @tags = Post.tag_counts_on(:tags)
185
+ end
186
+ end
187
+
188
+ View:
189
+
190
+ <% tag_cloud(@tags, %w(css1 css2 css3 css4)) do |tag, css_class| %>
191
+ <%= link_to tag.name, { :action => :tag, :id => tag.name }, :class => css_class %>
192
+ <% end %>
193
+
194
+ CSS:
195
+
196
+ .css1 { font-size: 1.0em; }
197
+ .css2 { font-size: 1.2em; }
198
+ .css3 { font-size: 1.4em; }
199
+ .css4 { font-size: 1.6em; }
200
+
201
+ == Contributors
202
+
203
+ * TomEric (i76) - Maintainer
204
+ * Michael Bleigh - Original Author
205
+ * Szymon Nowak - Rails 3.0 compatibility
206
+ * Jelle Vandebeeck - Rails 3.0 compatibility
207
+ * Brendan Lim - Related Objects
208
+ * Pradeep Elankumaran - Taggers
209
+ * Sinclair Bain - Patch King
210
+
211
+ === Patch Contributors
212
+
213
+ * tristanzdunn - Related objects of other classes
214
+ * azabaj - Fixed migrate down
215
+ * Peter Cooper - named_scope fix
216
+ * slainer68 - STI fix
217
+ * harrylove - migration instructions and fix-ups
218
+ * lawrencepit - cached tag work
219
+ * sobrinho - fixed tag_cloud helper
220
+
221
+ Copyright (c) 2007-2010 Michael Bleigh (http://mbleigh.com/) and Intridea Inc. (http://intridea.com/), released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,59 @@
1
+ begin
2
+ # Rspec 1.3.0
3
+ require 'spec/rake/spectask'
4
+
5
+ desc 'Default: run specs'
6
+ task :default => :spec
7
+ Spec::Rake::SpecTask.new do |t|
8
+ t.spec_files = FileList["spec/**/*_spec.rb"]
9
+ end
10
+
11
+ Spec::Rake::SpecTask.new('rcov') do |t|
12
+ t.spec_files = FileList["spec/**/*_spec.rb"]
13
+ t.rcov = true
14
+ t.rcov_opts = ['--exclude', 'spec']
15
+ end
16
+
17
+ rescue LoadError
18
+ # Rspec 2.0
19
+ require 'rspec/core/rake_task'
20
+
21
+ desc 'Default: run specs'
22
+ task :default => :spec
23
+ Rspec::Core::RakeTask.new do |t|
24
+ t.pattern = "spec/**/*_spec.rb"
25
+ end
26
+
27
+ Rspec::Core::RakeTask.new('rcov') do |t|
28
+ t.pattern = "spec/**/*_spec.rb"
29
+ t.rcov = true
30
+ t.rcov_opts = ['--exclude', 'spec']
31
+ end
32
+
33
+ rescue LoadError
34
+ puts "Rspec not available. Install it with: gem install rspec"
35
+ end
36
+
37
+ namespace 'rails2.3' do
38
+ task :spec do
39
+ gemfile = File.join(File.dirname(__FILE__), 'lib', 'acts_as_taggable_on', 'compatibility', 'Gemfile')
40
+ ENV['BUNDLE_GEMFILE'] = gemfile
41
+ Rake::Task['spec'].invoke
42
+ end
43
+ end
44
+
45
+ begin
46
+ require 'jeweler'
47
+ Jeweler::Tasks.new do |gemspec|
48
+ gemspec.name = "yetanothernguyen-acts-as-taggable-on"
49
+ gemspec.summary = "ActsAsTaggableOn is a tagging plugin for Rails that provides multiple tagging contexts on a single model."
50
+ gemspec.description = "With ActsAsTaggableOn, you could tag a single model on several contexts, such as skills, interests, and awards. It also provides other advanced functionality. This fork changes behavior of tagged_with on empty tag list. It will return an empty scope instead of an empty hash."
51
+ gemspec.email = "michael@intridea.com"
52
+ gemspec.homepage = "http://github.com/yetanothernguyen/acts-as-taggable-on"
53
+ gemspec.authors = ["Michael Bleigh"]
54
+ gemspec.files = FileList["[A-Z]*", "{generators,lib,spec,rails}/**/*"] - FileList["**/*.log"]
55
+ end
56
+ Jeweler::GemcutterTasks.new
57
+ rescue LoadError
58
+ puts "Jeweler not available. Install it with: gem install jeweler"
59
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.4
@@ -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
@@ -0,0 +1,30 @@
1
+ require "active_record"
2
+ require "action_view"
3
+
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+
6
+ require "acts_as_taggable_on/compatibility/active_record_backports" if ActiveRecord::VERSION::MAJOR < 3
7
+
8
+ require "acts_as_taggable_on/acts_as_taggable_on"
9
+ require "acts_as_taggable_on/acts_as_taggable_on/core"
10
+ require "acts_as_taggable_on/acts_as_taggable_on/collection"
11
+ require "acts_as_taggable_on/acts_as_taggable_on/cache"
12
+ require "acts_as_taggable_on/acts_as_taggable_on/ownership"
13
+ require "acts_as_taggable_on/acts_as_taggable_on/related"
14
+
15
+ require "acts_as_taggable_on/acts_as_tagger"
16
+ require "acts_as_taggable_on/tag"
17
+ require "acts_as_taggable_on/tag_list"
18
+ require "acts_as_taggable_on/tags_helper"
19
+ require "acts_as_taggable_on/tagging"
20
+
21
+ $LOAD_PATH.shift
22
+
23
+ if defined?(ActiveRecord::Base)
24
+ ActiveRecord::Base.extend ActsAsTaggableOn::Taggable
25
+ ActiveRecord::Base.send :include, ActsAsTaggableOn::Tagger
26
+ end
27
+
28
+ if defined?(ActionView::Base)
29
+ ActionView::Base.send :include, ActsAsTaggableOn::TagsHelper
30
+ end
@@ -0,0 +1,53 @@
1
+ module ActsAsTaggableOn
2
+ module Taggable
3
+ def taggable?
4
+ false
5
+ end
6
+
7
+ ##
8
+ # This is an alias for calling <tt>acts_as_taggable_on :tags</tt>.
9
+ #
10
+ # Example:
11
+ # class Book < ActiveRecord::Base
12
+ # acts_as_taggable
13
+ # end
14
+ def acts_as_taggable
15
+ acts_as_taggable_on :tags
16
+ end
17
+
18
+ ##
19
+ # Make a model taggable on specified contexts.
20
+ #
21
+ # @param [Array] tag_types An array of taggable contexts
22
+ #
23
+ # Example:
24
+ # class User < ActiveRecord::Base
25
+ # acts_as_taggable_on :languages, :skills
26
+ # end
27
+ def acts_as_taggable_on(*tag_types)
28
+ tag_types = tag_types.to_a.flatten.compact.map(&:to_sym)
29
+
30
+ if taggable?
31
+ write_inheritable_attribute(:tag_types, (self.tag_types + tag_types).uniq)
32
+ else
33
+ write_inheritable_attribute(:tag_types, tag_types)
34
+ class_inheritable_reader(:tag_types)
35
+
36
+ class_eval do
37
+ has_many :taggings, :as => :taggable, :dependent => :destroy, :include => :tag, :class_name => "ActsAsTaggableOn::Tagging"
38
+ has_many :base_tags, :through => :taggings, :source => :tag, :class_name => "ActsAsTaggableOn::Tag"
39
+
40
+ def self.taggable?
41
+ true
42
+ end
43
+
44
+ include ActsAsTaggableOn::Taggable::Core
45
+ include ActsAsTaggableOn::Taggable::Collection
46
+ include ActsAsTaggableOn::Taggable::Cache
47
+ include ActsAsTaggableOn::Taggable::Ownership
48
+ include ActsAsTaggableOn::Taggable::Related
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end