Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Adding taggable redux

  • Loading branch information...
commit 9581b6465a98b5811279cf2f54d50160924adbc7 1 parent d7cef03
@voodootikigod authored
Showing with 1,039 additions and 7 deletions.
  1. +1 −6 app/controllers/items_controller.rb
  2. +1 −0  app/models/item.rb
  3. +29 −0 db/migrate/20090721230823_add_acts_as_taggable_tables.rb
  4. +21 −1 db/schema.rb
  5. +20 −0 vendor/plugins/acts_as_taggable_redux/MIT-LICENSE
  6. +143 −0 vendor/plugins/acts_as_taggable_redux/README
  7. +22 −0 vendor/plugins/acts_as_taggable_redux/Rakefile
  8. +44 −0 vendor/plugins/acts_as_taggable_redux/acts_as_taggable_redux.gemspec
  9. +7 −0 ...gins/acts_as_taggable_redux/generators/acts_as_taggable_stylesheet/acts_as_taggable_stylesheet_generator.rb
  10. +7 −0 ...ins/acts_as_taggable_redux/generators/acts_as_taggable_stylesheet/templates/acts_as_taggable_stylesheet.css
  11. +7 −0 vendor/plugins/acts_as_taggable_redux/generators/acts_as_taggable_tables/acts_as_taggable_tables_generator.rb
  12. +29 −0 vendor/plugins/acts_as_taggable_redux/generators/acts_as_taggable_tables/templates/migration.rb
  13. +1 −0  vendor/plugins/acts_as_taggable_redux/init.rb
  14. +136 −0 vendor/plugins/acts_as_taggable_redux/lib/acts_as_taggable.rb
  15. +38 −0 vendor/plugins/acts_as_taggable_redux/lib/acts_as_taggable_helper.rb
  16. +9 −0 vendor/plugins/acts_as_taggable_redux/lib/acts_as_taggable_redux.rb
  17. +25 −0 vendor/plugins/acts_as_taggable_redux/lib/acts_as_tagger.rb
  18. +73 −0 vendor/plugins/acts_as_taggable_redux/lib/tag.rb
  19. +5 −0 vendor/plugins/acts_as_taggable_redux/lib/tagging.rb
  20. +20 −0 vendor/plugins/acts_as_taggable_redux/tasks/acts_as_taggable_tasks.rake
  21. +34 −0 vendor/plugins/acts_as_taggable_redux/test/acts_as_taggable_test.rb
  22. +10 −0 vendor/plugins/acts_as_taggable_redux/test/database.yml
  23. +104 −0 vendor/plugins/acts_as_taggable_redux/test/debug.log
  24. +47 −0 vendor/plugins/acts_as_taggable_redux/test/fixtures/taggings.yml
  25. +24 −0 vendor/plugins/acts_as_taggable_redux/test/fixtures/tags.yml
  26. +3 −0  vendor/plugins/acts_as_taggable_redux/test/fixtures/thing.rb
  27. +15 −0 vendor/plugins/acts_as_taggable_redux/test/fixtures/things.yml
  28. +3 −0  vendor/plugins/acts_as_taggable_redux/test/fixtures/user.rb
  29. +3 −0  vendor/plugins/acts_as_taggable_redux/test/fixtures/users.yml
  30. +27 −0 vendor/plugins/acts_as_taggable_redux/test/schema.rb
  31. +68 −0 vendor/plugins/acts_as_taggable_redux/test/tag_test.rb
  32. +13 −0 vendor/plugins/acts_as_taggable_redux/test/tagging_test.rb
  33. +50 −0 vendor/plugins/acts_as_taggable_redux/test/test_helper.rb
View
7 app/controllers/items_controller.rb
@@ -1,5 +1,5 @@
class ItemsController < ApplicationController
- before_filter :login_required, :except => [:show, :list_for_tag, :index, :search, :category, :new, :create]
+ before_filter :login_required, :except => [:show, :list_for_tag, :index, :search, :new, :create]
before_filter :admin_required, :only => [:destroy]
before_filter :permission_required, :only => [:edit, :update]
before_filter :do_pagination, :only => [:index, :list_for_tag, :list_for_tags, :search, :recently]
@@ -153,11 +153,6 @@ def search
end
end
- def category
- @category = Category.find_by_name(params[:id])
- go_404 and return unless @category
- @items = Item.find_all_for_all_tags(@category.query.split(/\s/))
- end
def recently
@last_checked_at = current_user.last_checked_at
View
1  app/models/item.rb
@@ -2,6 +2,7 @@ class Item < ActiveRecord::Base
belongs_to :user
has_many :comments
has_many :stars, :dependent => :destroy
+ acts_as_tagger
serialize :metadata
View
29 db/migrate/20090721230823_add_acts_as_taggable_tables.rb
@@ -0,0 +1,29 @@
+class AddActsAsTaggableTables < ActiveRecord::Migration
+ def self.up
+ create_table :tags do |t|
+ t.column :name, :string
+ t.column :taggings_count, :integer, :default => 0, :null => false
+ end
+ add_index :tags, :name
+ add_index :tags, :taggings_count
+
+ create_table :taggings do |t|
+ t.column :tag_id, :integer
+ t.column :taggable_id, :integer
+ t.column :taggable_type, :string
+ t.column :user_id, :integer
+ end
+
+ # Find objects for a tag
+ add_index :taggings, [:tag_id, :taggable_type]
+ add_index :taggings, [:user_id, :tag_id, :taggable_type]
+ # Find tags for an object
+ add_index :taggings, [:taggable_id, :taggable_type]
+ add_index :taggings, [:user_id, :taggable_id, :taggable_type]
+ end
+
+ def self.down
+ drop_table :tags
+ drop_table :taggings
+ end
+end
View
22 db/schema.rb
@@ -9,7 +9,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 15) do
+ActiveRecord::Schema.define(:version => 20090721230823) do
create_table "categories", :force => true do |t|
t.string "name"
@@ -68,6 +68,26 @@
t.integer "item_id", :limit => 11
end
+ create_table "taggings", :force => true do |t|
+ t.integer "tag_id", :limit => 11
+ t.integer "taggable_id", :limit => 11
+ t.string "taggable_type"
+ t.integer "user_id", :limit => 11
+ end
+
+ add_index "taggings", ["tag_id", "taggable_type"], :name => "index_taggings_on_tag_id_and_taggable_type"
+ add_index "taggings", ["user_id", "tag_id", "taggable_type"], :name => "index_taggings_on_user_id_and_tag_id_and_taggable_type"
+ add_index "taggings", ["taggable_id", "taggable_type"], :name => "index_taggings_on_taggable_id_and_taggable_type"
+ add_index "taggings", ["user_id", "taggable_id", "taggable_type"], :name => "index_taggings_on_user_id_and_taggable_id_and_taggable_type"
+
+ create_table "tags", :force => true do |t|
+ t.string "name"
+ t.integer "taggings_count", :limit => 11, :default => 0, :null => false
+ end
+
+ add_index "tags", ["name"], :name => "index_tags_on_name"
+ add_index "tags", ["taggings_count"], :name => "index_tags_on_taggings_count"
+
create_table "users", :force => true do |t|
t.string "login"
t.string "email"
View
20 vendor/plugins/acts_as_taggable_redux/MIT-LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2007 monki(Wesley Beary)
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
143 vendor/plugins/acts_as_taggable_redux/README
@@ -0,0 +1,143 @@
+ActsAsTaggableRedux
+===================
+
+Allows for user owned tags to be added to multiple classes, and makes tags easier to work with.
+
+
+Prerequisites
+=============
+
+Install Edge Rails before you get started so you get RESTful routing.
+
+ActsAsTaggableRedux depends on database tables to store tagging information. Create the migration for these tables with this command:
+
+ rake acts_as_taggable:db:create
+
+Then run the migration to create the tables with this command:
+
+ rake db:migrate
+
+Also you will need to add this to your user model:
+ acts_as_tagger
+
+OPTIONAL: The helper functions assume the pressence of a tags controller, that is what the tag clouds and tags will link to.
+
+OPTIONAL: To pretty up tag clouds and lists you can generate an example stylesheet with this command:
+
+ rake acts_as_taggable:stylesheet:create
+
+and then include this in your layouts that have tag clouds:
+
+ <%= stylesheet_link_tag 'acts_as_taggable_stylesheet' %>
+
+
+Example
+=======
+
+The following is an example of how you might integrate tags with an Item model.
+
+config/routes.rb
+ may.resource :items, :tags
+
+
+app/views/items/new.erb
+ <h1>New Item</h1>
+
+ <% form_for(:item, @item) do |f| -%>
+
+ <%= error_message_for :item %>
+
+ <b>Tags:</b> <%= f.text_field :tag_list -%>
+
+ <%= submit_tag "Save" -%>
+
+ <% end -%>
+
+if you want users to own taggings change the tags line to this
+ <b>Tags:</b> <%= f.text_field :tag_list, :value => @item.tag_list(user) -%>
+and add this line beneath it
+ <%= f.hidden_field :user_id, :value => user.id -%>
+
+app/views/items/show.erb
+ Item tagged with:
+ <% item.tags.each do |tag| -%>
+ <%= link_to_tag(tag) %>
+ <% end -%>
+
+app/views/items/edit.erb
+ <h1>New Item</h1>
+
+ <% form_for(:item, @item, :html => { :method => :post }) do |f| -%>
+
+ <%= error_messages_for :item %>
+
+ <b>Tags:</b> <%= f.text_field :tag_list -%>
+
+ <%= submit_tag "Save" -%>
+
+ <% end -%>
+
+
+app/controllers/items_controller.rb
+ class ItemController < ApplicationController
+ def new
+ @item = Item.new
+ end
+
+ def create
+ @item = Item.new(params[:item])
+
+ respond_to do |format|
+ if @item.save
+ flash[:notice] = 'Item was successfully created.'
+ format.html { redirect_to item_url(@item) }
+ format.xml { head :created, :location => item_url(@item) }
+ else
+ format.html { render :action => "new" }
+ format.xml { render :xml => @item.errors.to_xml }
+ end
+ end
+ end
+
+ def show
+ @item = Item.find(params[:id], :include => :tags)
+ end
+
+ def edit
+ @item = Item.find(params[:id])
+ end
+
+ def update
+ @item = Item.find(params[:id])
+
+ respond_to do |format|
+ if @item.update_attributes(params[:item])
+ flash[:notice] = 'Item was successfully updated.'
+ format.html { redirect_to item_url(@item) }
+ format.xml { head :updated, :location => item_url(@item) }
+ end
+ format.html { render :action => "edit"}
+ format.xml { render :xml => @item.errors.to_xml}
+ end
+ end
+ end
+
+
+
+Tag clouds
+==========
+
+Tag clouds are created by a helper function, and depend on the counter cache to get fast accurate counts. To ensure this keeps working properly, don't add new tags to a taggable in any way other than using the tag.tag(taggable) style. This will ensure that the caches don't lose track. Also, see the prerequisites for installing the stylesheet so that the tag cloud actually looks like a tag cloud. Otherwise, just pop into a view that you want the tag cloud to appear and type this:
+
+ <%= tag_cloud %>
+
+
+
+Contributing
+============
+
+Welcoming all pull requests on github.com at http://github.com/monki/acts_as_taggable_redux/tree/master or git://github.com/monki/acts_as_taggable_redux.git
+
+
+
+Copyright (c) 2008 monki(Wesley Beary), released under the MIT license
View
22 vendor/plugins/acts_as_taggable_redux/Rakefile
@@ -0,0 +1,22 @@
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+
+desc 'Default: run unit tests.'
+task :default => :test
+
+desc 'Test the acts_as_taggable_redux plugin.'
+Rake::TestTask.new(:test) do |t|
+ t.libs << 'lib'
+ t.pattern = 'test/**/*_test.rb'
+ t.verbose = true
+end
+
+desc 'Generate documentation for the acts_as_taggable_redux plugin.'
+Rake::RDocTask.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = 'ActsAsTaggableRedux'
+ rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.rdoc_files.include('README')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
View
44 vendor/plugins/acts_as_taggable_redux/acts_as_taggable_redux.gemspec
@@ -0,0 +1,44 @@
+Gem::Specification.new do |s|
+ s.name = 'acts_as_taggable_redux'
+ s.version = '0.0.1'
+ s.date = '2008-12-06'
+
+ s.summary = 'Allows for user owned tags to be added to multiple classes, and makes tags easier to work with.'
+ s.description = 'Allows for user owned tags to be added to multiple classes, and makes tags easier to work with.'
+
+ s.authors = ['Wesley Beary']
+ s.email = 'monki@geemus.com'
+ s.homepage = 'http://github.com/monki/acts_as_taggable_redux'
+
+ s.has_rdoc = false
+ s.files = [
+ 'generators/acts_as_taggable_tables/templates/migration.rb',
+ 'generators/acts_as_taggable_tables/acts_as_taggable_tables_generator.rb',
+ 'generators/acts_as_taggable_stylesheet/templates/acts_as_taggable_stylesheet.css',
+ 'generators/acts_as_taggable_stylesheet/acts_as_taggable_stylesheet_generator.rb',
+ 'init.rb',
+ 'lib/acts_as_taggable.rb',
+ 'lib/acts_as_tagger.rb',
+ 'lib/acts_as_taggable_helper.rb',
+ 'lib/acts_as_taggable_redux.rb',
+ 'lib/tag.rb',
+ 'lib/tagging.rb',
+ 'MIT-LICENSE',
+ 'Rakefile',
+ 'README',
+ 'tasks/acts_as_taggable_tasks.rake',
+ 'test/tagging_test.rb',
+ 'test/debug.log',
+ 'test/test_helper.rb',
+ 'test/fixtures/users.yml',
+ 'test/fixtures/tags.yml',
+ 'test/fixtures/things.yml',
+ 'test/fixtures/thing.rb',
+ 'test/fixtures/taggings.yml',
+ 'test/fixtures/user.rb',
+ 'test/acts_as_taggable_test.rb',
+ 'test/tag_test.rb',
+ 'test/database.yml',
+ 'test/schema.rb'
+ ]
+end
View
7 ...s/acts_as_taggable_redux/generators/acts_as_taggable_stylesheet/acts_as_taggable_stylesheet_generator.rb
@@ -0,0 +1,7 @@
+class ActsAsTaggableStylesheetGenerator < Rails::Generator::Base
+ def manifest
+ record do |m|
+ m.file "acts_as_taggable_stylesheet.css", "public/stylesheets/acts_as_taggable_stylesheet.css"
+ end
+ end
+end
View
7 .../acts_as_taggable_redux/generators/acts_as_taggable_stylesheet/templates/acts_as_taggable_stylesheet.css
@@ -0,0 +1,7 @@
+.hTagcloud .popularity { margin:0; padding:0; }
+.hTagcloud .popularity li { display:inline; text-decoration:none; }
+.hTagcloud .popularity .popular { font-size:1.0em; }
+.hTagcloud .popularity .v-popular { font-size:1.2em; }
+.hTagcloud .popularity .vv-popular { font-size:1.4em; }
+.hTagcloud .popularity .vvv-popular { font-size:1.6em; }
+.hTagcloud .popularity .vvvv-popular { font-size:1.8em; }
View
7 ...r/plugins/acts_as_taggable_redux/generators/acts_as_taggable_tables/acts_as_taggable_tables_generator.rb
@@ -0,0 +1,7 @@
+class ActsAsTaggableTablesGenerator < Rails::Generator::NamedBase
+ def manifest
+ record do |m|
+ m.migration_template 'migration.rb', 'db/migrate'
+ end
+ end
+end
View
29 vendor/plugins/acts_as_taggable_redux/generators/acts_as_taggable_tables/templates/migration.rb
@@ -0,0 +1,29 @@
+class AddActsAsTaggableTables < ActiveRecord::Migration
+ def self.up
+ create_table :tags do |t|
+ t.column :name, :string
+ t.column :taggings_count, :integer, :default => 0, :null => false
+ end
+ add_index :tags, :name
+ add_index :tags, :taggings_count
+
+ create_table :taggings do |t|
+ t.column :tag_id, :integer
+ t.column :taggable_id, :integer
+ t.column :taggable_type, :string
+ t.column :user_id, :integer
+ end
+
+ # Find objects for a tag
+ add_index :taggings, [:tag_id, :taggable_type]
+ add_index :taggings, [:user_id, :tag_id, :taggable_type]
+ # Find tags for an object
+ add_index :taggings, [:taggable_id, :taggable_type]
+ add_index :taggings, [:user_id, :taggable_id, :taggable_type]
+ end
+
+ def self.down
+ drop_table :tags
+ drop_table :taggings
+ end
+end
View
1  vendor/plugins/acts_as_taggable_redux/init.rb
@@ -0,0 +1 @@
+require 'acts_as_taggable_redux'
View
136 vendor/plugins/acts_as_taggable_redux/lib/acts_as_taggable.rb
@@ -0,0 +1,136 @@
+module ActiveRecord
+ module Acts #:nodoc:
+ module Taggable #:nodoc:
+ def self.included(base)
+ base.extend(ClassMethods)
+ end
+
+ module ClassMethods
+ def acts_as_taggable(options = {})
+ has_many :taggings, :as => :taggable, :dependent => :destroy, :include => :tag
+ has_many :tags, :through => :taggings, :order => 'LOWER(name) asc', :select => "DISTINCT tags.*"
+
+ after_save :update_tags
+
+ extend ActiveRecord::Acts::Taggable::SingletonMethods
+ include ActiveRecord::Acts::Taggable::InstanceMethods
+ end
+ end
+
+ module SingletonMethods
+ # Pass a tag string, returns taggables that match the tag string.
+ #
+ # Options:
+ # :match - Match taggables matching :all or :any of the tags, defaults to :any
+ # :user - Limits results to those owned by a particular user
+ def find_tagged_with(tags, options = {})
+ tagged_with_scope(tags, options) do
+ find(:all, :select => "DISTINCT #{table_name}.*")
+ end
+ end
+
+ def tagged_with_scope(tags, options={})
+ options.assert_valid_keys([:match, :order, :user])
+
+ tags = Tag.parse(tags)
+ return [] if tags.empty?
+
+ group = "#{table_name}_taggings.taggable_id HAVING COUNT(#{table_name}_taggings.taggable_id) >= #{tags.size}" if options[:match] == :all
+ conditions = sanitize_sql(["#{table_name}_tags.name IN (?)", tags])
+ conditions += sanitize_sql([" AND #{table_name}_taggings.user_id = ?", options[:user]]) if options[:user]
+
+ find_parameters = {
+ :joins => "LEFT OUTER JOIN #{Tagging.table_name} #{table_name}_taggings ON #{table_name}_taggings.taggable_id = #{table_name}.#{primary_key} AND #{table_name}_taggings.taggable_type = '#{name}' " +
+ "LEFT OUTER JOIN #{Tag.table_name} #{table_name}_tags ON #{table_name}_tags.id = #{table_name}_taggings.tag_id",
+ :conditions => conditions,
+ :group => group,
+ :order => options[:order]
+ }
+
+ with_scope(:find => find_parameters) { yield }
+ end
+
+ # Pass a tag string, returns taggables that match the tag string for a particular user.
+ #
+ # Options:
+ # :match - Match taggables matching :all or :any of the tags, defaults to :any
+ def find_tagged_with_by_user(tags, user, options = {})
+ options.assert_valid_keys([:match, :order])
+ find_tagged_with(tags, {:match => options[:match], :order => options[:order], :user => user})
+ end
+
+ # Returns an array of related tags.
+ # Related tags are all the other tags that are found on the models tagged with the provided tags.
+ #
+ # Pass either a tag, string, or an array of strings or tags.
+ #
+ # Options:
+ # :order - SQL Order how to order the tags. Defaults to "count DESC, tags.name".
+ # :match - Match taggables matching :all or :any of the tags, defaults to :any
+ def find_related_tags(tags, options = {})
+ #duplicated work, the tags are parsed twice. I need to elimidate this by making find_tagged_with
+ #accept an array of tags and not just a string
+ parsed_tags = Tag.parse(tags)
+ related_models = find_tagged_with(tags, :match => options.delete(:match))
+
+ return [] if related_models.blank?
+
+ related_ids = related_models.to_s(:db)
+
+ Tag.find(:all, options.merge({
+ :select => "#{Tag.table_name}.*, COUNT(#{Tag.table_name}.id) AS count",
+ :joins => "JOIN #{Tagging.table_name} ON #{Tagging.table_name}.taggable_type = '#{base_class.name}'
+AND #{Tagging.table_name}.taggable_id IN (#{related_ids})
+AND #{Tagging.table_name}.tag_id = #{Tag.table_name}.id",
+ :order => options[:order] || "count DESC, #{Tag.table_name}.name",
+ :group => "#{Tag.table_name}.id, #{Tag.table_name}.name HAVING #{Tag.table_name}.name NOT IN (#{parsed_tags.map { |n| quote_value(n) }.join(",")})"
+ }))
+ end
+ end
+
+ module InstanceMethods
+ def tag_list=(new_tag_list)
+ unless tag_list == new_tag_list
+ @new_tag_list = new_tag_list
+ end
+ end
+
+ def user_id=(new_user_id)
+ @new_user_id = new_user_id
+ super(new_user_id)
+ end
+
+ def tag_list(user = nil)
+ unless user
+ resiult = tags.collect { |tag| tag.name.include?(" ") ? %("#{tag.name}") : tag.name }.join(" ")
+ else
+ #TODO: make it work if I pass in an int instead of a user object
+ tags.find(:all, :conditions => ['"taggings"."user_id" = ?', user.id]).collect { |tag| tag.name.include?(" ") ? %("#{tag.name}") : tag.name }.uniq.join(" ")
+ end
+ end
+
+ def update_tags
+ if @new_tag_list
+ Tag.transaction do
+ unless @new_user_id
+ taggings.destroy_all
+ else
+ taggings.find(:all, :conditions => "user_id = #{@new_user_id}").each do |tagging|
+ tagging.destroy
+ end
+ end
+
+ Tag.parse(@new_tag_list).each do |name|
+ Tag.find_or_create_by_name(name).tag(self, @new_user_id)
+ end
+
+ tags.reset
+ taggings.reset
+ @new_tag_list = nil
+ end
+ end
+ end
+ end
+ end
+ end
+end
View
38 vendor/plugins/acts_as_taggable_redux/lib/acts_as_taggable_helper.rb
@@ -0,0 +1,38 @@
+module ActsAsTaggableHelper
+ # Create a link to the tag using restful routes and the rel-tag microformat
+ def link_to_tag(tag)
+ link_to(tag.name, tag_url(tag), :rel => 'tag')
+ end
+
+ # Generate a tag cloud of the top 100 tags by usage, uses the proposed hTagcloud microformat.
+ #
+ # Inspired by http://www.juixe.com/techknow/index.php/2006/07/15/acts-as-taggable-tag-cloud/
+ def tag_cloud(options = {})
+ options.assert_valid_keys(:limit, :conditions, :sort)
+ options.reverse_merge! :limit => 100, :sort => :name
+ sort = options.delete(:sort)
+
+ tags = Tag.find(:all, options.merge(:order => 'taggings_count DESC')).sort_by(&sort)
+
+ # TODO: add option to specify which classes you want and overide this if you want?
+ classes = %w(popular v-popular vv-popular vvv-popular vvvv-popular)
+
+ max, min = 0, 0
+ tags.each do |tag|
+ max = tag.taggings_count if tag.taggings_count > max
+ min = tag.taggings_count if tag.taggings_count < min
+ end
+
+ divisor = ((max - min) / classes.size) + 1
+
+ html = %(<div class="hTagcloud">\n)
+ html << %( <ul class="popularity">\n)
+ tags.each do |tag|
+ html << %( <li>)
+ html << link_to(tag.name, tag_url(tag), :class => classes[(tag.taggings_count - min) / divisor])
+ html << %(</li> \n)
+ end
+ html << %( </ul>\n)
+ html << %(</div>\n)
+ end
+end
View
9 vendor/plugins/acts_as_taggable_redux/lib/acts_as_taggable_redux.rb
@@ -0,0 +1,9 @@
+require 'acts_as_taggable'
+require 'acts_as_tagger'
+
+ActiveRecord::Base.send(:include, ActiveRecord::Acts::Taggable)
+ActiveRecord::Base.send(:include, ActiveRecord::Acts::Tagger)
+ActionView::Base.send(:include, ActsAsTaggableHelper)
+
+require 'tagging'
+require 'tag'
View
25 vendor/plugins/acts_as_taggable_redux/lib/acts_as_tagger.rb
@@ -0,0 +1,25 @@
+module ActiveRecord
+ module Acts #:nodoc:
+ module Tagger #:nodoc:
+ def self.included(base)
+ base.extend(ClassMethods)
+ end
+
+ module ClassMethods
+ def acts_as_tagger(options = {})
+ has_many :taggings
+ has_many :tags, :through => :taggings, :select => "DISTINCT #{Tag.table_name}.*", :order => "LOWER(name) asc"
+
+ extend ActiveRecord::Acts::Tagger::SingletonMethods
+ include ActiveRecord::Acts::Tagger::InstanceMethods
+ end
+ end
+
+ module SingletonMethods
+ end
+
+ module InstanceMethods
+ end
+ end
+ end
+end
View
73 vendor/plugins/acts_as_taggable_redux/lib/tag.rb
@@ -0,0 +1,73 @@
+class Tag < ActiveRecord::Base
+ has_many :taggings
+
+ # Parse a text string into an array of tokens for use as tags
+ def self.parse(list)
+ tag_names = []
+
+ return tag_names if list.blank?
+
+ # first, pull out the quoted tags
+ list.gsub!(/\"(.*?)\"\s*/) { tag_names << $1; "" }
+
+ # then, replace all commas with a space
+ list.gsub!(/,/, " ")
+
+ # then, get whatever is left
+ tag_names.concat(list.split(/\s/))
+
+ # delete any blank tag names
+ tag_names = tag_names.delete_if { |t| t.empty? }
+
+ # downcase all tags
+ tag_names = tag_names.map! { |t| t.downcase }
+
+ # remove duplicates
+ tag_names = tag_names.uniq
+
+ return tag_names
+ end
+
+ # Grab a distinct list of tags only for a particular type of taggable.
+ # For example, if you had a taggable Foo, you could get all tags used on Foo via:
+ #
+ # Tag.with_type_scope('Foo') { Tag.find(:all) }
+ #
+ # If no parameter is given, the scope does not take effect.
+ #
+ # pass in a user id to have it scope by user_id as well
+
+ def self.with_type_scope(taggable_type, user = nil)
+ if taggable_type
+ conditions = sanitize_sql(["taggable_type = ?", taggable_type])
+ conditions += sanitize_sql([" AND #{Tagging.table_name}.user_id = ?", user.id]) if user
+ with_scope(:find => {:select => "distinct #{Tag.table_name}.*", :joins => "left outer join #{Tagging.table_name} on #{Tagging.table_name}.tag_id = #{Tag.table_name}.id", :conditions => conditions, :group => "name"}) { yield }
+ else
+ yield
+ end
+ end
+
+ # Tag a taggable with this tag, optionally add user to add owner to tagging
+ def tag(taggable, user_id = nil)
+ taggings.create :taggable => taggable, :user_id => user_id
+ taggings.reset
+ @tagged = nil
+ end
+
+ # A list of all the objects tagged with this tag
+ def tagged
+ @tagged ||= taggings.collect(&:taggable)
+ end
+
+ # Compare tags by name
+ def ==(comparison_object)
+ super || name == comparison_object.to_s
+ end
+
+ # Return the tag's name
+ def to_s
+ name
+ end
+
+ validates_presence_of :name
+end
View
5 vendor/plugins/acts_as_taggable_redux/lib/tagging.rb
@@ -0,0 +1,5 @@
+class Tagging < ActiveRecord::Base
+ belongs_to :tag, :counter_cache => true
+ belongs_to :taggable, :polymorphic => true
+ belongs_to :user
+end
View
20 vendor/plugins/acts_as_taggable_redux/tasks/acts_as_taggable_tasks.rake
@@ -0,0 +1,20 @@
+namespace :acts_as_taggable do
+ namespace :db do
+ desc "Creates tag tables for use with acts_as_taggable"
+ task :create => :environment do
+ require 'rails_generator'
+ require 'rails_generator/scripts/generate'
+ raise "Task unavailable to this database (no migration support)" unless ActiveRecord::Base.connection.supports_migrations?
+ Rails::Generator::Scripts::Generate.new.run([ "acts_as_taggable_tables", "add_acts_as_taggable_tables" ])
+ end
+ end
+
+ namespace :stylesheet do
+ desc "Create tag stylesheet for use with acts_as_taggable"
+ task :create => :environment do
+ require 'rails_generator'
+ require 'rails_generator/scripts/generate'
+ Rails::Generator::Scripts::Generate.new.run([ "acts_as_taggable_stylesheet" ])
+ end
+ end
+end
View
34 vendor/plugins/acts_as_taggable_redux/test/acts_as_taggable_test.rb
@@ -0,0 +1,34 @@
+require File.dirname(__FILE__) + "/test_helper"
+
+class ActsAsTaggableTest < Test::Unit::TestCase
+ def test_find_tagged_with_any
+ assert_equal [things(:bear), things(:frog)].sort_by(&:id), Thing.find_tagged_with("animal")
+ assert_equal [things(:bear), things(:frog), things(:cactus)].sort_by(&:id), Thing.find_tagged_with("animal green")
+ assert_equal [], Thing.find_tagged_with("fake")
+
+ assert_equal [things(:bear), things(:frog)].sort_by(&:id), Thing.find_tagged_with("animal", :match => :any)
+ assert_equal [things(:bear), things(:frog), things(:cactus)].sort_by(&:id), Thing.find_tagged_with("animal green", :match => :any)
+ assert_equal [], Thing.find_tagged_with("fake", :match => :any)
+ end
+
+ def test_find_tagged_with_all
+ assert_equal [things(:bear), things(:frog)].sort_by(&:id), Thing.find_tagged_with("animal", :match => :all)
+ assert_equal [things(:frog)].sort_by(&:id), Thing.find_tagged_with("animal green", :match => :all)
+ assert_equal [], Thing.find_tagged_with("fake", :match => :all)
+ assert_equal [], Thing.find_tagged_with("animal plant", :match => :all)
+ end
+
+ def test_tag_list
+ assert_equal things(:bear).tag_list, "animal \"not green\""
+ assert_equal things(:frog).tag_list, "animal green"
+ assert_not_equal things(:frog).tag_list, "animal \"not green\""
+ end
+
+ def test_update_tags
+ assert_equal things(:bear).tag_list, "animal \"not green\""
+ things(:bear).tag_list = 'animal "not green" favorite'
+ assert_equal things(:bear).tag_list, "animal \"not green\""
+ things(:bear).update_tags
+ assert_equal things(:bear).tag_list, "animal favorite \"not green\""
+ end
+end
View
10 vendor/plugins/acts_as_taggable_redux/test/database.yml
@@ -0,0 +1,10 @@
+mysql:
+ :adapter: mysql
+ :host: localhost
+ :username: root
+ :password:
+ :database: rails_plugin_test
+
+sqlite3:
+ :adapter: sqlite3
+ :database: ':memory:'
View
104 vendor/plugins/acts_as_taggable_redux/test/debug.log
@@ -0,0 +1,104 @@
+# Logfile created on Thu May 15 14:17:58 -0500 2008 by logger.rb/1.5.2.9
+ SQL (0.000346) select sqlite_version(*)
+ SQL (0.000000) SQLite3::SQLException: no such table: tags: DROP TABLE tags
+ SQL (0.000336) CREATE TABLE tags ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255) DEFAULT NULL, "taggings_count" integer DEFAULT 0 NOT NULL) 
+ SQL (0.000171) CREATE INDEX "index_tags_on_name" ON tags ("name")
+ SQL (0.000153) CREATE INDEX "index_tags_on_taggings_count" ON tags ("taggings_count")
+ SQL (0.000000) SQLite3::SQLException: no such table: taggings: DROP TABLE taggings
+ SQL (0.000188) CREATE TABLE taggings ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "tag_id" integer DEFAULT NULL, "taggable_id" integer DEFAULT NULL, "taggable_type" varchar(255) DEFAULT NULL, "user_id" integer DEFAULT NULL) 
+ SQL (0.000153) CREATE INDEX "index_taggings_on_tag_id_and_taggable_type" ON taggings ("tag_id", "taggable_type")
+ SQL (0.000166) CREATE INDEX "index_taggings_on_user_id_and_tag_id_and_taggable_type" ON taggings ("user_id", "tag_id", "taggable_type")
+ SQL (0.000156) CREATE INDEX "index_taggings_on_taggable_id_and_taggable_type" ON taggings ("taggable_id", "taggable_type")
+ SQL (0.000161) CREATE INDEX "index_taggings_on_user_id_and_taggable_id_and_taggable_type" ON taggings ("user_id", "taggable_id", "taggable_type")
+ SQL (0.000000) SQLite3::SQLException: no such table: things: DROP TABLE things
+ SQL (0.000176) CREATE TABLE things ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255) DEFAULT NULL) 
+ SQL (0.000000) SQLite3::SQLException: no such table: users: DROP TABLE users
+ SQL (0.000177) CREATE TABLE users ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "username" varchar(255) DEFAULT NULL) 
+ SQL (0.000184) CREATE TABLE schema_info (version integer)
+ SQL (0.000069) INSERT INTO schema_info (version) VALUES(0)
+ SQL (0.000082) UPDATE schema_info SET version = 0
+ Thing Load (0.000163) SELECT * FROM things WHERE (things."id" = 1) 
+ Thing Load (0.000162) SELECT * FROM things WHERE (things."id" = 2) 
+ Thing Load (0.001725) SELECT DISTINCT things.* FROM things LEFT OUTER JOIN taggings things_taggings ON things_taggings.taggable_id = things.id AND things_taggings.taggable_type = 'Thing' LEFT OUTER JOIN tags things_tags ON things_tags.id = things_taggings.tag_id WHERE (things_tags.name IN ('animal')) GROUP BY things_taggings.taggable_id HAVING COUNT(things_taggings.taggable_id) = 1
+ Thing Load (0.001072) SELECT DISTINCT things.* FROM things LEFT OUTER JOIN taggings things_taggings ON things_taggings.taggable_id = things.id AND things_taggings.taggable_type = 'Thing' LEFT OUTER JOIN tags things_tags ON things_tags.id = things_taggings.tag_id WHERE (things_tags.name IN ('animal','green')) GROUP BY things_taggings.taggable_id HAVING COUNT(things_taggings.taggable_id) = 2
+ Thing Load (0.000946) SELECT DISTINCT things.* FROM things LEFT OUTER JOIN taggings things_taggings ON things_taggings.taggable_id = things.id AND things_taggings.taggable_type = 'Thing' LEFT OUTER JOIN tags things_tags ON things_tags.id = things_taggings.tag_id WHERE (things_tags.name IN ('fake')) GROUP BY things_taggings.taggable_id HAVING COUNT(things_taggings.taggable_id) = 1
+ Thing Load (0.000893) SELECT DISTINCT things.* FROM things LEFT OUTER JOIN taggings things_taggings ON things_taggings.taggable_id = things.id AND things_taggings.taggable_type = 'Thing' LEFT OUTER JOIN tags things_tags ON things_tags.id = things_taggings.tag_id WHERE (things_tags.name IN ('animal','plant')) GROUP BY things_taggings.taggable_id HAVING COUNT(things_taggings.taggable_id) = 2
+ Thing Load (0.000182) SELECT * FROM things WHERE (things."id" = 1) 
+ Thing Load (0.000160) SELECT * FROM things WHERE (things."id" = 2) 
+ Thing Load (0.000919) SELECT DISTINCT things.* FROM things LEFT OUTER JOIN taggings things_taggings ON things_taggings.taggable_id = things.id AND things_taggings.taggable_type = 'Thing' LEFT OUTER JOIN tags things_tags ON things_tags.id = things_taggings.tag_id WHERE (things_tags.name IN ('animal')) 
+ Thing Load (0.000181) SELECT * FROM things WHERE (things."id" = 3) 
+ Thing Load (0.000909) SELECT DISTINCT things.* FROM things LEFT OUTER JOIN taggings things_taggings ON things_taggings.taggable_id = things.id AND things_taggings.taggable_type = 'Thing' LEFT OUTER JOIN tags things_tags ON things_tags.id = things_taggings.tag_id WHERE (things_tags.name IN ('animal','green')) 
+ Thing Load (0.001076) SELECT DISTINCT things.* FROM things LEFT OUTER JOIN taggings things_taggings ON things_taggings.taggable_id = things.id AND things_taggings.taggable_type = 'Thing' LEFT OUTER JOIN tags things_tags ON things_tags.id = things_taggings.tag_id WHERE (things_tags.name IN ('fake')) 
+ Thing Load (0.000792) SELECT DISTINCT things.* FROM things LEFT OUTER JOIN taggings things_taggings ON things_taggings.taggable_id = things.id AND things_taggings.taggable_type = 'Thing' LEFT OUTER JOIN tags things_tags ON things_tags.id = things_taggings.tag_id WHERE (things_tags.name IN ('animal')) 
+ Thing Load (0.000842) SELECT DISTINCT things.* FROM things LEFT OUTER JOIN taggings things_taggings ON things_taggings.taggable_id = things.id AND things_taggings.taggable_type = 'Thing' LEFT OUTER JOIN tags things_tags ON things_tags.id = things_taggings.tag_id WHERE (things_tags.name IN ('animal','green')) 
+ Thing Load (0.000694) SELECT DISTINCT things.* FROM things LEFT OUTER JOIN taggings things_taggings ON things_taggings.taggable_id = things.id AND things_taggings.taggable_type = 'Thing' LEFT OUTER JOIN tags things_tags ON things_tags.id = things_taggings.tag_id WHERE (things_tags.name IN ('fake')) 
+ Thing Load (0.000173) SELECT * FROM things WHERE (things."id" = 1) 
+ Tag Load (0.010343) SELECT tags.* FROM tags INNER JOIN taggings ON tags.id = taggings.tag_id WHERE ((taggings.taggable_type = 'Thing') AND (taggings.taggable_id = 1)) ORDER BY name asc
+ Thing Load (0.000226) SELECT * FROM things WHERE (things."id" = 2) 
+ Tag Load (0.000703) SELECT tags.* FROM tags INNER JOIN taggings ON tags.id = taggings.tag_id WHERE ((taggings.taggable_type = 'Thing') AND (taggings.taggable_id = 2)) ORDER BY name asc
+ Thing Load (0.000232) SELECT * FROM things WHERE (things."id" = 1) 
+ Tag Load (0.000751) SELECT tags.* FROM tags INNER JOIN taggings ON tags.id = taggings.tag_id WHERE ((taggings.taggable_type = 'Thing') AND (taggings.taggable_id = 1)) ORDER BY name asc
+ Tagging Load Including Associations (0.000550) SELECT taggings."id" AS t0_r0, taggings."tag_id" AS t0_r1, taggings."taggable_id" AS t0_r2, taggings."taggable_type" AS t0_r3, taggings."user_id" AS t0_r4, tags."id" AS t1_r0, tags."name" AS t1_r1, tags."taggings_count" AS t1_r2 FROM taggings LEFT OUTER JOIN tags ON tags.id = taggings.tag_id WHERE (taggings.taggable_id = 1 AND taggings.taggable_type = 'Thing') 
+ Tag Update (0.000111) UPDATE tags SET "taggings_count" = "taggings_count" - 1 WHERE ("id" = 1) 
+ Tag Update (0.000093) UPDATE tags SET "taggings_count" = "taggings_count" - 1 WHERE ("id" = 1) 
+ Tagging Destroy (0.000096)  DELETE FROM taggings
+ WHERE "id" = 1
+
+ Tag Update (0.000095) UPDATE tags SET "taggings_count" = "taggings_count" - 1 WHERE ("id" = 4) 
+ Tag Update (0.000092) UPDATE tags SET "taggings_count" = "taggings_count" - 1 WHERE ("id" = 4) 
+ Tagging Destroy (0.000088)  DELETE FROM taggings
+ WHERE "id" = 2
+
+ Tag Load (0.000196) SELECT * FROM tags WHERE (tags."name" = 'not green') LIMIT 1
+ Tagging Create (0.000163) INSERT INTO taggings ("tag_id", "taggable_type", "taggable_id", "user_id") VALUES(4, 'Thing', 1, NULL)
+ Tag Load (0.000240) SELECT * FROM tags WHERE (tags."id" = 4) 
+ Tag Update (0.000105) UPDATE tags SET "taggings_count" = "taggings_count" + 1 WHERE ("id" = 4) 
+ Tag Update (0.000097) UPDATE tags SET "taggings_count" = "taggings_count" + 1 WHERE ("id" = 4) 
+ Tag Load (0.000217) SELECT * FROM tags WHERE (tags."name" = 'animal') LIMIT 1
+ Tagging Create (0.000175) INSERT INTO taggings ("tag_id", "taggable_type", "taggable_id", "user_id") VALUES(1, 'Thing', 1, NULL)
+ Tag Load (0.000225) SELECT * FROM tags WHERE (tags."id" = 1) 
+ Tag Update (0.000102) UPDATE tags SET "taggings_count" = "taggings_count" + 1 WHERE ("id" = 1) 
+ Tag Update (0.000093) UPDATE tags SET "taggings_count" = "taggings_count" + 1 WHERE ("id" = 1) 
+ Tag Load (0.000186) SELECT * FROM tags WHERE (tags."name" = 'favorite') LIMIT 1
+ Tagging Create (0.000114) INSERT INTO taggings ("tag_id", "taggable_type", "taggable_id", "user_id") VALUES(5, 'Thing', 1, NULL)
+ Tag Load (0.000177) SELECT * FROM tags WHERE (tags."id" = 5) 
+ Tag Update (0.000097) UPDATE tags SET "taggings_count" = "taggings_count" + 1 WHERE ("id" = 5) 
+ Tag Update (0.000091) UPDATE tags SET "taggings_count" = "taggings_count" + 1 WHERE ("id" = 5) 
+ Tag Load (0.000787) SELECT tags.* FROM tags INNER JOIN taggings ON tags.id = taggings.tag_id WHERE ((taggings.taggable_type = 'Thing') AND (taggings.taggable_id = 1)) ORDER BY name asc
+ Tag Load (0.000196) SELECT * FROM tags WHERE (tags."id" = 1) 
+ Tag Load (0.000176) SELECT * FROM tags WHERE (tags."id" = 1) 
+ Tag Load (0.000174) SELECT * FROM tags WHERE (tags."id" = 1) 
+ Tag Load (0.000208) SELECT * FROM tags WHERE (tags."id" = 5) 
+ Tagging Load (0.000101) SELECT * FROM taggings WHERE (taggings.tag_id = 5) 
+ Thing Load (0.000155) SELECT * FROM things WHERE (things."id" = 1) 
+ Tagging Create (0.000130) INSERT INTO taggings ("tag_id", "taggable_type", "taggable_id", "user_id") VALUES(5, 'Thing', 1, NULL)
+ Tag Load (0.000187) SELECT * FROM tags WHERE (tags."id" = 5) 
+ Tag Update (0.000100) UPDATE tags SET "taggings_count" = "taggings_count" + 1 WHERE ("id" = 5) 
+ Tag Update (0.000093) UPDATE tags SET "taggings_count" = "taggings_count" + 1 WHERE ("id" = 5) 
+ Tagging Load (0.000212) SELECT * FROM taggings WHERE (taggings.tag_id = 5) 
+ Thing Load (0.000158) SELECT * FROM things WHERE (things."id" = 1) 
+ Thing Load (0.000169) SELECT * FROM things WHERE (things."id" = 1) 
+ Thing Load (0.000189) SELECT * FROM things WHERE (things."id" = 2) 
+ Tag Load (0.000175) SELECT * FROM tags WHERE (tags."id" = 1) 
+ Tagging Load (0.000343) SELECT * FROM taggings WHERE (taggings.tag_id = 1) 
+ Thing Load (0.000282) SELECT * FROM things WHERE (things."id" = 1) 
+ Thing Load (0.000176) SELECT * FROM things WHERE (things."id" = 2) 
+ Tag Load (0.000228) SELECT * FROM tags WHERE (tags."id" = 2) 
+ Tagging Load (0.000357) SELECT * FROM taggings WHERE (taggings.tag_id = 2) 
+ Thing Load (0.000180) SELECT * FROM things WHERE (things."id" = 3) 
+ Thing Load (0.000172) SELECT * FROM things WHERE (things."id" = 4) 
+ Tagging Load (0.000268) SELECT * FROM taggings WHERE (taggings."id" = 1) 
+ Tagging Load (0.000233) SELECT * FROM taggings WHERE (taggings."id" = 3) 
+ Tag Load (0.000204) SELECT * FROM tags WHERE (tags."id" = 1) 
+ Tagging Load (0.000623) SELECT * FROM taggings WHERE (taggings.tag_id = 1) 
+ Tagging Load (0.000215) SELECT * FROM taggings WHERE (taggings."id" = 5) 
+ Tagging Load (0.000207) SELECT * FROM taggings WHERE (taggings."id" = 7) 
+ Tag Load (0.000195) SELECT * FROM tags WHERE (tags."id" = 1) 
+ Tag Load (0.000344) SELECT * FROM tags WHERE (tags."id" = 1) 
+ Tagging Load (0.000212) SELECT * FROM taggings WHERE (taggings."id" = 1) 
+ Tag Load (0.000175) SELECT * FROM tags WHERE (tags."id" = 1) 
+ Tag Load (0.000180) SELECT * FROM tags WHERE (tags."id" = 2) 
+ Thing Load (0.000163) SELECT * FROM things WHERE (things."id" = 1) 
+ Tagging Load (0.000216) SELECT * FROM taggings WHERE (taggings."id" = 1) 
+ Thing Load (0.000168) SELECT * FROM things WHERE (things."id" = 1) 
+ Thing Load (0.000159) SELECT * FROM things WHERE (things."id" = 2) 
View
47 vendor/plugins/acts_as_taggable_redux/test/fixtures/taggings.yml
@@ -0,0 +1,47 @@
+bear_animal:
+ id: 1
+ taggable_id: 1
+ taggable_type: Thing
+ tag_id: 1
+
+bear_not_green:
+ id: 2
+ taggable_id: 1
+ taggable_type: Thing
+ tag_id: 4
+
+frog_animal:
+ id: 3
+ taggable_id: 2
+ taggable_type: Thing
+ tag_id: 1
+
+frog_green:
+ id: 4
+ taggable_id: 2
+ taggable_type: Thing
+ tag_id: 3
+
+cactus_plant:
+ id: 5
+ taggable_id: 3
+ taggable_type: Thing
+ tag_id: 2
+
+cactus_green:
+ id: 6
+ taggable_id: 3
+ taggable_type: Thing
+ tag_id: 3
+
+orange_plant:
+ id: 7
+ taggable_id: 4
+ taggable_type: Thing
+ tag_id: 2
+
+orange_not_green:
+ id: 8
+ taggable_id: 4
+ taggable_type: Thing
+ tag_id: 4
View
24 vendor/plugins/acts_as_taggable_redux/test/fixtures/tags.yml
@@ -0,0 +1,24 @@
+animal:
+ id: 1
+ name: animal
+ taggings_count: 2
+
+plant:
+ id: 2
+ name: plant
+ taggings_count: 2
+
+green:
+ id: 3
+ name: green
+ taggings_count: 2
+
+not_green:
+ id: 4
+ name: not green
+ taggings_count: 2
+
+favorite:
+ id: 5
+ name: favorite
+ taggings_count: 0
View
3  vendor/plugins/acts_as_taggable_redux/test/fixtures/thing.rb
@@ -0,0 +1,3 @@
+class Thing < ActiveRecord::Base
+ acts_as_taggable
+end
View
15 vendor/plugins/acts_as_taggable_redux/test/fixtures/things.yml
@@ -0,0 +1,15 @@
+bear:
+ id: 1
+ name: bear
+
+frog:
+ id: 2
+ name: frog
+
+cactus:
+ id: 3
+ name: cactus
+
+orange:
+ id: 4
+ name: orange
View
3  vendor/plugins/acts_as_taggable_redux/test/fixtures/user.rb
@@ -0,0 +1,3 @@
+class User < ActiveRecord::Base
+ acts_as_tagger
+end
View
3  vendor/plugins/acts_as_taggable_redux/test/fixtures/users.yml
@@ -0,0 +1,3 @@
+monki:
+ id: 1
+ username: monki
View
27 vendor/plugins/acts_as_taggable_redux/test/schema.rb
@@ -0,0 +1,27 @@
+ActiveRecord::Schema.define :version => 0 do
+ create_table :tags, :force => true do |t|
+ t.column :name, :string
+ t.column :taggings_count, :integer, :default => 0, :null => false
+ end
+ add_index :tags, :name
+ add_index :tags, :taggings_count
+
+ create_table :taggings, :force => true do |t|
+ t.column :tag_id, :integer
+ t.column :taggable_id, :integer
+ t.column :taggable_type, :string
+ t.column :user_id, :integer
+ end
+ add_index :taggings, [:tag_id, :taggable_type]
+ add_index :taggings, [:user_id, :tag_id, :taggable_type]
+ add_index :taggings, [:taggable_id, :taggable_type]
+ add_index :taggings, [:user_id, :taggable_id, :taggable_type]
+
+ create_table :things, :force => true do |t|
+ t.column :name, :string
+ end
+
+ create_table :users, :force => true do |t|
+ t.column :username, :string
+ end
+end
View
68 vendor/plugins/acts_as_taggable_redux/test/tag_test.rb
@@ -0,0 +1,68 @@
+require File.dirname(__FILE__) + "/test_helper"
+
+class TagTest < Test::Unit::TestCase
+ def test_taggings
+ assert_equal [taggings(:bear_animal), taggings(:frog_animal)], tags(:animal).taggings
+ assert_not_equal [taggings(:cactus_plant), taggings(:orange_plant)], tags(:animal).taggings
+ end
+
+ def test_parse_does_not_change_param
+ list = 'a b c'
+ original = list.dup
+ Tag.parse(list)
+ assert_equal list, original
+ end
+
+ def test_parse_blank
+ assert_equal [], Tag.parse(nil)
+ assert_equal [], Tag.parse('')
+ end
+
+ def test_parse_single_tag
+ assert_equal ['a'], Tag.parse('a')
+ assert_equal ['a'], Tag.parse('"a"')
+ end
+
+ def test_parse_quoted_tags
+ assert_equal ['a b', 'c'], Tag.parse('"a b" c')
+ end
+
+ def test_parse_comma_dilineation
+ assert_equal ['a', 'b', 'c'], Tag.parse('a,b,c')
+ assert_equal ['a', 'b', 'c'], Tag.parse('a,b,c')
+ end
+
+ def test_parse_quotes_and_commas
+ assert_equal ['a,b', 'c'], Tag.parse('"a,b",c')
+ end
+
+ def test_parse_removes_whitespace
+ assert_equal ['a', 'b', 'c'], Tag.parse('a b, c')
+ end
+
+ def test_parse_removes_duplicates
+ assert_equal ['a', 'b', 'c'], Tag.parse('a b a c a b')
+ end
+
+ def test_tag
+ assert !tags(:favorite).tagged.include?(things(:bear))
+ tags(:favorite).tag(things(:bear))
+ assert tags(:favorite).tagged.include?(things(:bear))
+ end
+
+ def test_tagged
+ assert_equal [things(:bear), things(:frog)], tags(:animal).tagged
+ assert_not_equal [things(:bear), things(:frog)], tags(:plant).tagged
+ end
+
+ def test_equality
+ assert_equal tags(:animal), tags(:animal)
+ assert_equal Tag.find(1), Tag.find(1)
+ assert_equal Tag.new(:name => 'mineral'), Tag.new(:name => 'mineral')
+ assert_not_equal Tag.new(:name => 'mineral'), tags(:animal)
+ end
+
+ def test_to_s
+ assert_equal tags(:animal).name, tags(:animal).to_s
+ end
+end
View
13 vendor/plugins/acts_as_taggable_redux/test/tagging_test.rb
@@ -0,0 +1,13 @@
+require File.dirname(__FILE__) + "/test_helper"
+
+class TaggingTest < Test::Unit::TestCase
+ def test_taggable
+ assert_equal things(:bear), taggings(:bear_animal).taggable
+ assert_not_equal things(:frog), taggings(:bear_animal).taggable
+ end
+
+ def test_tag
+ assert_equal tags(:animal), taggings(:bear_animal).tag
+ assert_not_equal tags(:plant), taggings(:bear_animal).tag
+ end
+end
View
50 vendor/plugins/acts_as_taggable_redux/test/test_helper.rb
@@ -0,0 +1,50 @@
+ENV["RAILS_ENV"] = "test"
+require File.expand_path(File.dirname(__FILE__) + "/../../../../config/environment")
+require 'test_help'
+require 'test/unit'
+
+require File.dirname(__FILE__) + '/../lib/acts_as_taggable'
+require File.dirname(__FILE__) + '/../lib/tag'
+require File.dirname(__FILE__) + '/../lib/tagging'
+
+ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + '/debug.log')
+ActiveRecord::Base.configurations = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
+ActiveRecord::Base.establish_connection(ENV['DB'] || 'mysql')
+
+load(File.dirname(__FILE__) + '/schema.rb')
+
+Test::Unit::TestCase.fixture_path = File.dirname(__FILE__) + '/fixtures/'
+$LOAD_PATH.unshift(Test::Unit::TestCase.fixture_path)
+
+class Test::Unit::TestCase
+ # Transactional fixtures accelerate your tests by wrapping each test method
+ # in a transaction that's rolled back on completion. This ensures that the
+ # test database remains unchanged so your fixtures don't have to be reloaded
+ # between every test method. Fewer database queries means faster tests.
+ #
+ # Read Mike Clark's excellent walkthrough at
+ # http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting
+ #
+ # Every Active Record database supports transactions except MyISAM tables
+ # in MySQL. Turn off transactional fixtures in this case; however, if you
+ # don't care one way or the other, switching from MyISAM to InnoDB tables
+ # is recommended.
+ self.use_transactional_fixtures = true
+
+ # Instantiated fixtures are slow, but give you @david where otherwise you
+ # would need people(:david). If you don't want to migrate your existing
+ # test cases which use the @david style and don't mind the speed hit (each
+ # instantiated fixtures translates to a database query per test method),
+ # then set this back to true.
+ self.use_instantiated_fixtures = false
+
+ # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
+ # If you need to control the loading order (due to foreign key constraints etc), you'll
+ # need to change this line to explicitly name the order you desire.
+ #
+ # Note: You'll currently still have to declare fixtures explicitly in integration tests
+ # -- they do not yet inherent this setting
+ fixtures :all
+
+ # Add more helper methods to be used by all tests here...
+end
Please sign in to comment.
Something went wrong with that request. Please try again.