Ruby on Rails
ActsAsTaggablePluginHowto (Version #277)

——-
sorry to top-post, but it should be known that someone named josh peek has a repository of this along w/ a broken migration file, and an MIT license under his name (why is he claiming copyright, exactly? does one get a copyright for tweaking DHH code?). if you get his copy it won’t work. his tests also have ‘require’ files on his machine’s path, e.g.

require ‘/Users/josh/Source/rails/activerecord/lib/active_record’

that’s going to be a difficult task for the interpreter, eh?

i thought maybe it’s edge rails (i’m only 1.2.3)?

another e.g.:
create_table :taggings do |t|
t.integer :tag_id, :taggable_id
t.string :taggable_type
end

is this the future or a huge mistake?
——-

This plugin worked great for me.
I recommend ignoring the warnings below and going straight to the howto – its very easy.

Before you read any of the info below:
I spent two days fooling around with the acts_as_taggable plugin, applying all of the modifications below and it still didn’t work very well. After searching around I found acts_as_taggable_on_steroids which is a complete rewrite, or version 2 of this plugin and works great. I highly recommend it if you want to save yourself from a major headache! Look in the README and Tests for instructions and usage examples.

Is someone actively maintaining this plugin? Why aren’t the cool hacks shown below already part of the plugin? There is also a great tag_cloud method described here

(another post on this plugin can be found at rails.co.za )

(Some french stuff on acts_as_taggable_on_steroids plugin can be read at this address : Nuage de tag avec RubyOnRails)

The Instructions
First, this plugin is different from the acts_as_taggable gem, foremost in that it uses features that are not in Rails 1.0 (like has_many :through and :as). The plugin lets you use tags across models, unlike the gem, and is preferable in most cases. So either upgrade to Rails 1.1, or if you can handle being on the bleeding edge, install the “edge version of rails”: EdgeRails. To switch to EdgeRails, in your application’s main directory do:

rake rails:freeze:edge</pre>

To undo this later, just type:

rake rails:unfreeze

Next, install the acts_as_taggable plugin:

script/plugin install acts_as_taggable</pre>

Now create a migration to add two tables to store the tagging information:

<pre>script/generate migration add_tag_support</pre>

Insert the following:

<pre> class AddTagSupport < ActiveRecord::Migration def self.up #Table for your Tags create_table :tags do |t| t.column :name, :string end create_table :taggings do |t| t.column :tag_id, :integer #id of tagged object t.column :taggable_id, :integer #type of object tagged t.column :taggable_type, :string end # Index your tags/taggings add_index :tags, :name add_index :taggings, [:tag_id, :taggable_id, :taggable_type] end

def self.down drop_table :taggings drop_table :tags end

end



Run Rake to add the tables to the database.

rake db:migrate



An example:

First create a model that you want to tag. In this example books. So we generate a database table books and generate the model:

script/generate model Book</pre>

Next we add the acts_as_taggable line to the modelfile (book.rb):


 class Book < ActiveRecord::Base
  acts_as_taggable
 end

Finally we should have created the tags and taggings tables so we can start tagging:


 mybook = Book.new
 mybook.tag_with('red library book')
 mybook.save
 mybook.tag_list #gives back 'red library book'
 Book.find_tagged_with('library') #gives your Book
</pre>

This generates three tags with the names ‘red’, ‘library’ and ‘book’ in the tag table. Next it creates rows in the taggings table with the taggable_type set to ‘Book’ and the tag_id set to the corresponding tag in the tag table. The taggable_id is set to the id of the book in your books table.

Nice huh?

ALSO: The View (forms)
<pre> <%= text_field_tag 'tag_list', @item.tags.collect{|t| t.name}.join(" ") %> </pre>

if you are using the alias below, you can use this in the view instead and then you don’t have to do the controller-fu below.

<pre> <%= text_field 'item', 'tag_list' %> </pre>

AND The Controller (if using the default generated scaffolding).
For example in say books_controller.rb add the following to your ‘update’ and ‘create’ methods:
<pre> @book.tag_with(params[:tag_list])


- David Andrew Thompson

Question:
If tag_with was named tag_list= it would just work in most controllers/views with normal @model.update(params[:model]) calls, instead of having to do it manually like above.

Is there a reason why its not called tag_list=, or that the method isn’t aliased for this purpose?

If anyone wants to do this, just add:

alias tag_list= tag_with

under the tag_with method in acts_as_taggable.rb

-Nate K.

AND The Fixtures. tags.yml looks like this:


big:
  id: 1
  name: Big
  
small:
  id: 2
  name: Small

taggings.yml looks like this:


big_elephant:
  id: 1
  tag_id: 1
  taggable_id: 50 # Elephant is an Animal record with id 50
  taggable_type: Animal

small_beer:
id: 1
tag_id: 1
taggable_id: 20 # Beer is a Beverage record with id 20
taggable_type: Beverage

Note:
This post has some useful information about how the code in /vendor/plugins/acts_as_taggable/lib works.

Note:
I was having issues with the tag.collect putting information in single quotes and on an update that information begin submitted to the database as “’test” “series’” instead of “test series” so I corrected line 52:


 tags.collect { |tag| tag.name.include?(" ") ? "'#{tag.name}'" : tag.name }.join(" ")
</pre>

so that the tags will be in double quotes and insert into the database correctly:


 tags.collect { |tag| tag.name.include?(" ") ? '"' +"#{tag.name}" + '"' : tag.name }.join(" ")

Note:
I needed the tags_count method, so I put “my own” in module SingletonMethods (in acts_as_taggable.rb), like this:


 def tags_count(options)
   sql = "SELECT  tags.id AS id, tags.name AS name, COUNT(*) AS count FROM tags, taggings, #{table_name} "
   sql << "WHERE taggings.taggable_id = #{table_name}.#{primary_key} AND taggings.tag_id = tags.id "
   sql << "AND #{sanitize_sql(options[:conditions])} " if options[:conditions]
   sql << "GROUP BY tags.name "
   sql << "HAVING count #{options[:count]} " if options[:count]
   sql << "ORDER BY #{options[:order]} " if options[:order]
   sql << "LIMIT #{options[:limit]} " if options[:limit]
   find_by_sql(sql)
end


For instance:

@tags = Post.tags_count :conditions => "posts.posttype = 'public'", :order => 'count DESC'

Note: *
The tag_with is destructive, it deletes all previous tags which is not always what you want on an edit. I added the following method: EO


  def add_tags(list)          
    Tag.transaction do
      Tag.parse(list).each do |name|
        if acts_as_taggable_options[:from]
          send(acts_as_taggable_options[:from]).tags.find_or_create_by_name(name).on(self)
        else
          Tag.find_or_create_by_name(name).on(self)
        end
      end
    end
  end      
</pre>
This should be added to acts_as_taggable.rb
*Further note:
After much confusion, it was finally noted that add_tags was a deprecated association method (?!). Thus, no edits to it were working… Change the name of the above to add_tag, add_tag_list, or something similar, and all will be well.

another addition to the above:
In order to prevent multiple additions to taggable on the same tag change this:

 
  Tag.find_or_create_by_name(name).on(self)

To

 t = Tag.find_or_create_by_name(name)
 t.on(self) unless self.tags.include? t


*Note: *
ClassMethod for filtering tags by the Class of the item being tagged. This lets you filter tag to those available for a certain class. Used to assign roles to a users in a system.
It is an ugly hack as it should be an instance method that uses self.class to find out the jind od the class it is after.


def class_tagged(class_type)
  @taggings = Tagging.find_all_by_taggable_type(class_type)
  @tags = Hash.new
  @taggings.each do |tagging|
    @tags[tagging.tag.name]= tagging.tag
  end
  return @tags.values
end
</pre>

*… response to above? *
The above can be accomplished with a new ClassMethod. The following allows you to retrieve all unique tags for a given Class (as an array). I am guessing you would like to have this capability if you had multiple models that were acts_as_taggable, and wanted to list the tags for only a certain model. At the time of writing this my application only has one model, so I cannot test with multiple models. -markG


-- acts_as_taggable.rb 
-
- (in module ClassMethods) —-

def tag_list
@taggings = Tagging.find_all_by_taggable_type(ActiveRecord::Base.send(:class_name_of_active_record_descendant, self).to_s)
return @taggings.collect { |tagging| tagging.tag.name }.uniq
end

—- usage —-
Mymodel.tag_list

A Better Solution to Get Tags by Model?
Rather than implementing a whole new method, a line added to the existing self.tag method in tag.rb allows you to retrieve tags by model name.

By adding the following line between lines 4 and 5:


query << " AND taggings.taggable_type = #{options[:taggable_type]}'" if options[:taggable_type] != nil

Our method will now look like this:


  def self.tags(options = {})
    query = "select tags.id, name, count(*) as count"
    query << " from taggings, tags"
    query << " where tags.id = tag_id"
    query << " AND taggings.taggable_type = #{options[:taggable_type]}'" if options[:taggable_type] != nil
    query << " group by tag_id"
    query << " order by #{options[:order]}" if options[:order] != nil
    query << " limit #{options[:limit]}" if options[:limit] != nil
    tags = Tag.find_by_sql(query)
  end

We can call this as so:

@tags = Tag.tags(:order => "name", :taggable_type => "post")

I’ve fully documented this in my article, Modifiy Acts_As_Taggable to Return Tags By Model, including both this version and a version that follows Rails conventions more closely.

Note
User-specific acts_as_taggable functionality

Bath and Shower
Fragrance
Gift Sets
Hair Care
Makeup
Men’s Grooming
Shaving and Hair Removal
Skin Care
Tools and Accessories

Baby Apparel
Baby Bathing & Skin Care
Baby Bedding
Baby Car Seats
Baby Diapering
Baby Feeding
For Moms
Baby Furniture
Baby Gear
Baby Gifts
Baby Health & Baby Care
Nursery Décor
Potty Training
Baby Safety
Baby Strollers

Books – Business & Investing
Books – Children’s Books
Books – Comics & Graphic Novels
Books – Computers & Internet
Books – Cooking, Food & Wine
Books – Entertainment
Books – Gay & Lesbian
Books – Health, Mind & Body
Books – History
Books – Home & Garden
Books – Law
Books – Literature & Fiction
Books – Medicine
Books – Mystery & Thrillers
Books – Nonfiction
Books – Outdoors & Nature
Books – Parenting & Families
Books – Professional & Technical
Books – Reference
Books – Religion & Spirituality
Books – Romance
Books – Science
Books – Science Fiction & Fantasy
Books – Sports
Books – Teens
Books – Travel

Camera & Photo – Accessories
Camera & Photo – Camcorders
Camera & Photo – Digital Cameras
Camera & Photo – Film Cameras
Camera & Photo – Optics
Camera & Photo – Printers & Scanners

Health & Personal Care – Baby & Child Care
Health & Personal Care – Food & Snacks
Health & Personal Care – Health & Personal Care Outlet Store
Health & Personal Care – Health Care
Health & Personal Care – House Supplies
Health & Personal Care – Nutrition & Fitness
Health & Personal Care – Personal Care
Health & Personal Care – Sexual Wellness

Computers – Computer Add-Ons
Computers – Desktops
Computers – Handhelds & PDAs
Computers – Notebooks

Electronics – Accessories & Supplies
Electronics – Audio & Video
Electronics – Camera & Photo
Electronics – Car Electronics
Electronics – Computers & Add-Ons
Electronics – GPS & Navigation
Electronics – Home Automation & Security
Electronics – Office Electronics
Electronics – Service & Replacement Plans

Gourmet Food – Appetizers & Hors d’oeuvres
Gourmet Food – Baking Supplies
Gourmet Food – Beverages
Gourmet Food – Bread
Gourmet Food – Breakfast Foods
Gourmet Food – Candy
Gourmet Food – Cheese
Gourmet Food – Chocolate
Gourmet Food – Coffee & Tea
Gourmet Food – Cookies
Gourmet Food – Dairy Foods & Eggs
Gourmet Food – Desserts
Gourmet Food – Fruits & Vegetables
Gourmet Food – Gourmet Gifts
Gourmet Food – Jams, Jellies & Preserves
Gourmet Food – Meat, Game & Pâtés
Gourmet Food – Oils, Vinegars & Salad Dressings
Gourmet Food – Pasta, Beans, Grains & Rice
Gourmet Food – Prepared Meals
Gourmet Food – Salsas & Condiments
Gourmet Food – Seafood & Caviar
Gourmet Food – Seasonings, Herbs & Spices
Gourmet Food – Snack Food
Gourmet Food – Soups & Stocks

Grocery – Appetizers & Hors D’Oeuvres
Grocery – Baking Supplies
Grocery – Beverages
Grocery – Boxed Meals & Side Dishes
Grocery – Breads
Grocery – Breakfast Foods
Grocery – Canned & Packaged Goods
Grocery – Coffee, Tea & Cocoa
Grocery – Condiments, Sauces & Spreads
Grocery – Dairy & Eggs
Grocery – Desserts & Pastries
Grocery – Fruits & Vegetables
Grocery – Health & Family
Grocery – Herbs, Spices & Seasonings
Grocery – Household Supplies
Grocery – Meats
Grocery – Pasta & Grains
Grocery – Pet Supplies
Grocery – Seafood
Grocery – Snacks, Cookies & Candy

Home & Garden – Backyard Birding
Home & Garden – Bar Tools & Glasses
Home & Garden – Bedding & Bath
Home & Garden – Coffee, Tea & Espresso
Home & Garden – Cook’s Tools & Gadgets
Home & Garden – Cookware & Baking
Home & Garden – Cutlery
Home & Garden – Fresh Flowers & Indoor Plants
Home & Garden – Furniture & Décor
Home & Garden – Gardening Tools
Home & Garden – Grills, Smokers & Outdoor Cooking
Home & Garden – Heating & Lighting
Home & Garden – Kitchen & Table Linens
Home & Garden – Large Appliances
Home & Garden – Leisure & Fitness
Home & Garden – Outdoor Décor
Home & Garden – Patio Furniture
Home & Garden – Pest Control
Home & Garden – Pet Supplies
Home & Garden – Plants & Planting
Home & Garden – Small Appliances
Home & Garden – Tableware
Home & Garden – Vacuums, Cleaning & Storage
Home & Garden – Weather Instruments
Home & Garden – Wine Accessories

Industrial & Scientific – Adhesive Tapes
Industrial & Scientific – Fasteners
Industrial & Scientific – Industrial Abrasives
Industrial & Scientific – Industrial Adhesives
Industrial & Scientific – Industrial Cutting Tools
Industrial & Scientific – Industrial Hoses
Industrial & Scientific – Material Handling Equipment
Industrial & Scientific – Mechanical Components
Industrial & Scientific – Precision Measurement Products
Industrial & Scientific – Raw Materials

Jewelry – Accessories
Jewelry – Body Jewelry
Jewelry – Bracelets
Jewelry – Brooches & Pins
Jewelry – Charms
Jewelry – Children’s Jewelry
Jewelry – Earrings
Jewelry – Engagement
Jewelry – Jewelry Sets
Jewelry – Men’s Jewelry
Jewelry – Necklaces & Pendants
Jewelry – Religious Jewelry
Jewelry – Rings
Jewelry – Wedding & Anniversary

Kindle Store – Advice & How-to
Kindle Store – Arts & Entertainment
Kindle Store – Biographies & Memoirs
Kindle Store – Business & Investing
Kindle Store – Children’s Chapter Books
Kindle Store – Computers & Internet
Kindle Store – Fantasy
Kindle Store – Fiction
Kindle Store – History
Kindle Store – Humor
Kindle Store – Lifestyle & Home
Kindle Store – Literary Fiction
Kindle Store – Mystery & Thrillers
Kindle Store – Nonfiction
Kindle Store – Parenting & Families
Kindle Store – Politics & Current Events
Kindle Store – Reference
Kindle Store – Religion & Spirituality
Kindle Store – Romance
Kindle Store – Science
Kindle Store – Science Fiction
Kindle Store – Sports
Kindle Store – Travel

Kitchen & Housewares – Bar Tools & Glasses
Kitchen & Housewares – Coffee, Tea & Espresso
Kitchen & Housewares – Cook’s Tools & Gadgets
Kitchen & Housewares – Cookware & Baking
Kitchen & Housewares – Cutlery
Kitchen & Housewares – Dining Room Furniture
Kitchen & Housewares – Kitchen & Table Linens
Kitchen & Housewares – Kitchen Furniture
Kitchen & Housewares – Small Appliances
Kitchen & Housewares – Storage & Organization
Kitchen & Housewares – Tableware
Kitchen & Housewares – Wine Accessories

Magazine Subscriptions – Arts & Crafts
Magazine Subscriptions – Automotive
Magazine Subscriptions – Bridal
Magazine Subscriptions – Business & Finance
Magazine Subscriptions – Children’s
Magazine Subscriptions – Computer & Internet
Magazine Subscriptions – Electronics & Audio
Magazine Subscriptions – Entertainment
Magazine Subscriptions – Family & Parenting
Magazine Subscriptions – Fashion & Style
Magazine Subscriptions – Food & Gourmet
Magazine Subscriptions – Games & Hobbies
Magazine Subscriptions – Gay & Lesbian
Magazine Subscriptions – Health & Fitness
Magazine Subscriptions – History
Magazine Subscriptions – Home & Garden
Magazine Subscriptions – International
Magazine Subscriptions – Lifestyle & Cultures
Magazine Subscriptions – Literary
Magazine Subscriptions – Men’s Interest
Magazine Subscriptions – Music
Magazine Subscriptions – News & Politics
Magazine Subscriptions – Pets
Magazine Subscriptions – Religion & Spirituality
Magazine Subscriptions – Science & Nature
Magazine Subscriptions – Sports & Leisure
Magazine Subscriptions – Teens
Magazine Subscriptions – Travel & Regional
Magazine Subscriptions – Women’s Interest

Miscellaneous – Aircraft
Miscellaneous – Antiques
Miscellaneous – Coins
Miscellaneous – Collectibles
Miscellaneous – General
Miscellaneous – Other Products
Miscellaneous – Scientific Supplies
Miscellaneous – Stamps
Miscellaneous – Vehicles
Miscellaneous – Watercraft

MP3 Downloads – MP3 Albums
MP3 Downloads – MP3 Songs

Music – Alternative Rock
Music – Blues
Music – Broadway & Vocalists
Music – Children’s Music
Music – Christian & Gospel
Music – Classic Rock
Music – Classical
Music – Country
Music – Dance & DJ
Music – Folk
Music – Hard Rock & Metal
Music – International
Music – Jazz
Music – Latin Music
Music – Miscellaneous
Music – New Age
Music – Pop
Music – R&B
Music – Rap & Hip-Hop
Music – Rock
Music – Soundtracks

Classical Music – Ballads
Classical Music – Canons
Classical Music – Concertos
Classical Music – Etudes
Classical Music – Fantasies
Classical Music – Fugues
Classical Music – Improvisation
Classical Music – Inventions
Classical Music – Lullabies & Berceuse
Classical Music – Oratorio
Classical Music – Preludes
Classical Music – Requiems, Elegies & Tombeau
Classical Music – Rondos
Classical Music – Scherzo
Classical Music – Serenades & Divertimentos
Classical Music – Short Forms
Classical Music – Sonatas
Classical Music – Suites
Classical Music – Symphonies
Classical Music – Theatrical, Incidental & Program Music
Classical Music – Toccatas
Classical Music – Variations

Musical Instruments – Band & Orchestra
Musical Instruments – Bass Guitars
Musical Instruments – DJ, Electronic Music & Karaoke
Musical Instruments – Drums & Percussion
Musical Instruments – Folk & World Instruments
Musical Instruments – Guitars
Musical Instruments – Instrument Accessories
Musical Instruments – Keyboards
Musical Instruments – Live Sound & Stage
Musical Instruments – Recording Equipment

Office Products – Business Presentation Supplies
Office Products – Educational Supplies
Office Products – Mailroom Supplies
Office Products – Office Furniture & Accessories
Office Products – Office Lighting
Office Products – Office Supplies

Cell Phones & Service – All
Cell Phones & Service – Bluetooth
Cell Phones & Service – Camera
Cell Phones & Service – E-mail
Cell Phones & Service – Flip
Cell Phones & Service – Kid’s
Cell Phones & Service – Mobile Broadband Cards
Cell Phones & Service – MP3
Cell Phones & Service – PDA
Cell Phones & Service – Prepaid
Cell Phones & Service – Video
Cell Phones & Service – Wi-Fi

Software – Business & Office
Software – Children’s Software
Software – Education & Reference
Software – Graphics
Software – Home & Hobbies
Software – Language & Travel
Software – Linux
Software – Macintosh
Software – Networking
Software – Operating Systems
Software – Outlet
Software – Personal Finance
Software – Programming
Software – Software for Handhelds
Software – Utilities
Software – Video & Music
Software – Web Development

Sports & Outdoors – Accessories
Sports & Outdoors – Airsoft
Sports & Outdoors – Apparel
Sports & Outdoors – Archery
Sports & Outdoors – Badminton
Sports & Outdoors – Ballet & Dance
Sports & Outdoors – Baseball
Sports & Outdoors – Basketball
Sports & Outdoors – Boating
Sports & Outdoors – Bowling
Sports & Outdoors – Boxing
Sports & Outdoors – Camping & Hiking
Sports & Outdoors – Cheerleading
Sports & Outdoors – Climbing
Sports & Outdoors – Crew
Sports & Outdoors – Cricket
Sports & Outdoors – Curling
Sports & Outdoors – Cycling & Wheel Sports
Sports & Outdoors – Disc Sports
Sports & Outdoors – Diving
Sports & Outdoors – Dog Sports
Sports & Outdoors – Equestrian Sports
Sports & Outdoors – Exercise & Fitness
Sports & Outdoors – Fan Shop
Sports & Outdoors – Fencing
Sports & Outdoors – Field Hockey
Sports & Outdoors – Fishing
Sports & Outdoors – Football
Sports & Outdoors – Game Room
Sports & Outdoors – Golf
Sports & Outdoors – Gymnastics
Sports & Outdoors – Hockey
Sports & Outdoors – Hunting
Sports & Outdoors – Jai Alai
Sports & Outdoors – Kayaking
Sports & Outdoors – Lacrosse
Sports & Outdoors – Lawn Games
Sports & Outdoors – Martial Arts
Sports & Outdoors – Motor Sports
Sports & Outdoors – Paddle Court Sports
Sports & Outdoors – Paintball
Sports & Outdoors – Pilates
Sports & Outdoors – Polo
Sports & Outdoors – Racquetball
Sports & Outdoors – Rodeo
Sports & Outdoors – Rugby
Sports & Outdoors – Running
Sports & Outdoors – RV Equipment
Sports & Outdoors – Scooters
Sports & Outdoors – Shoes
Sports & Outdoors – Skateboarding
Sports & Outdoors – Skating
Sports & Outdoors – Skydiving
Sports & Outdoors – Sledding
Sports & Outdoors – Snow Skiing
Sports & Outdoors – Snowboarding
Sports & Outdoors – Snowmobiling
Sports & Outdoors – Snowshoeing
Sports & Outdoors – Soccer
Sports & Outdoors – Softball
Sports & Outdoors – Sports Medicine
Sports & Outdoors – Squash
Sports & Outdoors – Surfing
Sports & Outdoors – Swimming
Sports & Outdoors – Tennis & Racquet Sports
Sports & Outdoors – Track & Field
Sports & Outdoors – Triathlon
Sports & Outdoors – Volleyball
Sports & Outdoors – Water Polo
Sports & Outdoors – Water Sports
Sports & Outdoors – Windsurfing
Sports & Outdoors – Wrestling
Sports & Outdoors – Yoga

Tools & Hardware – Air Tools
Tools & Hardware – Appliances
Tools & Hardware – Building Supplies & Heavy Equipment
Tools & Hardware – Electrical
Tools & Hardware – Hand Tools
Tools & Hardware – Hardware
Tools & Hardware – Heating & Cooling
Tools & Hardware – Home Improvement Outlet
Tools & Hardware – Lawn & Garden
Tools & Hardware – Lighting
Tools & Hardware – Organization & Storage
Tools & Hardware – Painting Tools & Supplies
Tools & Hardware – Plumbing
Tools & Hardware – Power Tool Accessories
Tools & Hardware – Power Tools
Tools & Hardware – Safety & Security

Toys & Games – Action Figures
Toys & Games – Activities & Amusements
Toys & Games – Arts & Crafts
Toys & Games – Bikes, Skates & Ride-Ons
Toys & Games – Construction, Blocks & Models
Toys & Games – Dolls
Toys & Games – Electronics for Kids
Toys & Games – Games
Toys & Games – Hobbies
Toys & Games – Kids’ Furniture & Room Décor
Toys & Games – Learning & Education
Toys & Games – Music
Toys & Games – Party Supplies
Toys & Games – Play Vehicles
Toys & Games – Preschool
Toys & Games – Pretend Play & Dress-up
Toys & Games – Puzzles
Toys & Games – Sports & Outdoor Play
Toys & Games – Stuffed Animals & Plush
Toys & Games – Toy Figures & Playsets

Unbox Video Downloads – International
Unbox Video Downloads – Movies
Unbox Video Downloads – Nonfiction
Unbox Video Downloads – TV

DVD – Action & Adventure
DVD – African American Cinema
DVD – Animation
DVD – Anime & Manga
DVD – Art House & International
DVD – Classics
DVD – Comedy
DVD – Cult Movies
DVD – Documentary
DVD – Drama
DVD – Educational
DVD – Fitness & Yoga
DVD – Gay & Lesbian
DVD – Horror
DVD – Kids & Family
DVD – Military & War
DVD – Music Video & Concerts
DVD – Musicals & Performing Arts
DVD – Mystery & Suspense
DVD – Science Fiction & Fantasy
DVD – Special Interests
DVD – Sports
DVD – Television
DVD – Westerns

"Computer & Video Games – ":http://astore.amazon.com/vgamesbuy-20

VHS – Action & Adventure
VHS – African American Cinema
VHS – Animation
VHS – Anime & Manga
VHS – Art House & International
VHS – Boxed Sets
VHS – Classics
VHS – Comedy
VHS – Cult Movies
VHS – Documentary
VHS – Drama
VHS – Educational
VHS – Fitness
VHS – Gay & Lesbian
VHS – Horror
VHS – Kids & Family
VHS – Military & War
VHS – Music Video & Concerts
VHS – Musicals & Performing Arts
VHS – Mystery & Suspense
VHS – Science Fiction & Fantasy
VHS – Spanish Language
VHS – Special Interests
VHS – Sports
VHS – Television
VHS – Westerns
VHS – Widescreen

Watches – Accessories
Watches – Casual Watches
Watches – Collectible Watches
Watches – Dress Watches
Watches – Fashion Watches
Watches – Pocket Watches
Watches – Sport Watches

Note
I wanted to allow multiple word tags (like “New York Yankees”). This little modification in tags.rb lets you send in an array of anything (preferably strings) to use as your tags, instead of breaking up a string into single-word tags.


  def self.parse(list)
    unless list.kind_of? Array
      tag_names = []

      # first, pull out the quoted tags
      list.gsub!(/"(.*?)"s*/ ) { tag_names << $1; "" }

      # then, replace all commas with a space
      list.gsub!(/,/, " ")

      # then, get whatever's left
      tag_names.concat list.split(/s/)

      # strip whitespace from the names
      tag_names = tag_names.map { |t| t.strip }

      # delete any blank tag names
      tag_names = tag_names.delete_if { |t| t.empty? }
    
      return tag_names
    else
      tag_names = list.collect {|tag| tag.nil? ? nil : tag.to_s}
      return tag_names.compact
    end
  end

find_tagged_with

On ALL tags, instead of ANY

The default method find_tagged_with will search for any of the tags, and doesn’t return unique results.

This method will do a strict tag search and only return unique results. (works in mysql… does it work in other db engines?)


   def find_tagged_with!(list)
    find_by_sql([
      "SELECT #{table_name}.* FROM #{table_name} " +
      "WHERE #{table_name}.#{primary_key} in (" +
      "  SELECT taggable_id FROM taggings, tags " +
      "    WHERE tags.id=taggings.tag_id " +
      "     AND taggings.taggable_type = ? " +
      "     AND tags.name IN (?) " + 
      "    GROUP BY taggable_id " + 
      "    HAVING count(tags.id) >= ? " + 
      "  )",
      acts_as_taggable_options[:taggable_type], list, list.to_a.length
    ])
  end

find_tagged_with with duplicate tags gotcha

The above method find_tagged_with! will behave strangely when duplicate tags are introduced (acts_as_taggable doesn’t check/remove for dupes by default and they’re easy to get in a large list if users are entering tags). Changing the last line of Tag.parse like this solves the issue:


-    return tag_names
+    return tag_names.uniq

find_tagged_with on ALL tags, unique results, sorted by relevance


        def find_tagged_with(list)
          find_by_sql([
            "SELECT #{table_name}.*, COUNT(tags.id) AS count FROM #{table_name}, tags, taggings " +
            "WHERE #{table_name}.#{primary_key} = taggings.taggable_id " +
            "AND taggings.taggable_type = ? " +
            "AND taggings.tag_id = tags.id AND tags.name IN (?)" +
						"GROUP BY posts.id ORDER BY count DESC",
            acts_as_taggable_options[:taggable_type], list
          ])
        end

Acts_as_taggable – Pagination

The following opens the pagination class back up adds the abilty to filter based on a single tag. Pass a :tag => “tag” and the pagination with be base on though s items that are tagged with it. Belongs in acts_as_taggable.rb. EO


module ActionController
   module Pagination
       MY_OPTIONS = {
         :tag        => 'All'
       }
     DEFAULT_OPTIONS.merge!(MY_OPTIONS) {|key, old, new| old} 
     alias old_find_collection_for_pagination find_collection_for_pagination
     def find_collection_for_pagination(model, options, paginator)
       models = old_find_collection_for_pagination(model, options, paginator)
       if options[:tag]=="All"
         models
       else
         models.delete_if {|m| !m.is_tagged_with?(options[:tag])}
       end
     end
   end
end

Note
I tried the acts as taggable pagination fix as described above and it didn’t work for me. However, I did solve my problem with the following code when paginating through a list of tags:

<pre> def show_all_tags per_page = 12 if params[:id] then @tag_title = params[:id] @tags = params[:id].split.map {|o| CGI::unescape(o)} @members = Member.find_tagged_with(@tags) @members_pages, @members = paginate(Member, {:conditions => ['tags.name = ?', @tag_title], :include => [:tags], :per_page => per_page}) else redirect_to :action => 'list' end end </pre>
-Dave Hoefler

Dave, it probably didn’t work because you also need to add an is_tagged_with? method under the InstanceMethods of acts_as_taggable.rb like this:


      module InstanceMethods
        ... 
        
        def is_tagged_with?(tag)
          tags.include?(tag)
        end
      end

-JB

Yet Another Pagination Solution for acts_as_taggable

This uses the more powerful AR find method. Replace the find_tagged_with method on the act_as_taggable.rb with:


def find_tagged_with(list, options = {})
  find(:all,
  :from => "#{table_name}, tags, taggings", 
  :conditions => ["#{table_name}.#{primary_key} = taggings.taggable_id AND taggings.taggable_type = ? AND taggings.tag_id = tags.id AND tags.name IN (?)", acts_as_taggable_options[:taggable_type], list], 
  :offset => options[:offset], 
  :limit => options[:limit], 
  :order => options[:order])
end

Enjoy,
Sergio Bayona

And another method to paginate
This uses will_paginate and the Paginator gem, described here

Question:
Does anyone have a method for tag clouds with the plugin?

-Doug M.

Answer:

Here ’s a tag cloud that will work with the plugin.

Tom Fakes has an article on creating tag clouds for the acts_as_taggable gem, NOT the plugin.

I have an article with another way to do tag clouds
blog.wolfman.com

General Notes on Usage

When to Save

Do not try to apply tags to a Model during save. You will end up with a “stack too deep” error. You’re best to apply them :after_save

If you are seeing entries in the tagging table which are being added but the taggable_id is not filled in, it is because you are trying to add the tags too early. Follow the above advice and call tag_with only after the object has been saved.

Question:
I have overidden both acts_as_taggable.rb and tag.rb with slightly different versions in my application. When I make a call to acts_as_taggable from my web app all is peachy. However when I make the same call using script/runner it uses my acts_as_taggable but the original tag.rb. Any ideas? Is there a hard-coded reference to the original tag.rb

Adding count cache field

If you want to keep track and easily display the number of objects the tag is refering to, all you need to do is add the automagic field taggings_count to your tag table and enable cache in the belongs_to field. After that you can get the number of references by querying tag.taggings_count. For full writeup, go here: Counter for acts as taggable

Question:
Post
has_many :comments
Comment
belongs_to :Post, :counter_cache=>true
acts_as_taggable #alos enable counter cache

I find comments_count cannot work properly after added acts_as_taggable plugin
who can tell me why?

Question:
How do you delete a tag?

Question:
How do you validate that a tag was entered when adding from a form?

A. Add the following to tag.rb: validates_presence_of :name

Question:
I tried the plugin. I’m sure a add the line acts_as_taggable in the model I would like to tag. But I got a method missing error when I’m testing tag_with(). Any idea what I missed? THX

A. I fixed it with a server reload.

Question:
How do you use this pluging with STI and record the :taggable_type as the subclass, not the base class? Example….

class Foo < ActiveRecord::Base
end

class SubFoo < Foo
acts_as_taggable
end

In script/console,

c = SubFoo.create(…..)
c.tag_with(“mysubfoo stuff tag”)

Then in the database I execute the query

"select distinct taggable_type from taggings;
mysql output → Foo

Thanks in advance!

Question:
Is there a way to have multiple groups of tags on the same model. Say I want a set of tags that relates to how the model would be displayed in the layout and another that would be used for related links and be actually shown to the user. If I just group them all together I’d end up having a lot of very cryptic tags showing up in my list to the user. I’ve looked and cannot find anything about this.

-Christopher G.

——-
sorry to top-post, but it should be known that someone named josh peek has a repository of this along w/ a broken migration file, and an MIT license under his name (why is he claiming copyright, exactly? does one get a copyright for tweaking DHH code?). if you get his copy it won’t work. his tests also have ‘require’ files on his machine’s path, e.g.

require ‘/Users/josh/Source/rails/activerecord/lib/active_record’

that’s going to be a difficult task for the interpreter, eh?

i thought maybe it’s edge rails (i’m only 1.2.3)?

another e.g.:
create_table :taggings do |t|
t.integer :tag_id, :taggable_id
t.string :taggable_type
end

is this the future or a huge mistake?
——-

This plugin worked great for me.
I recommend ignoring the warnings below and going straight to the howto – its very easy.

Before you read any of the info below:
I spent two days fooling around with the acts_as_taggable plugin, applying all of the modifications below and it still didn’t work very well. After searching around I found acts_as_taggable_on_steroids which is a complete rewrite, or version 2 of this plugin and works great. I highly recommend it if you want to save yourself from a major headache! Look in the README and Tests for instructions and usage examples.

Is someone actively maintaining this plugin? Why aren’t the cool hacks shown below already part of the plugin? There is also a great tag_cloud method described here

(another post on this plugin can be found at rails.co.za )

(Some french stuff on acts_as_taggable_on_steroids plugin can be read at this address : Nuage de tag avec RubyOnRails)

The Instructions
First, this plugin is different from the acts_as_taggable gem, foremost in that it uses features that are not in Rails 1.0 (like has_many :through and :as). The plugin lets you use tags across models, unlike the gem, and is preferable in most cases. So either upgrade to Rails 1.1, or if you can handle being on the bleeding edge, install the “edge version of rails”: EdgeRails. To switch to EdgeRails, in your application’s main directory do:

rake rails:freeze:edge</pre>

To undo this later, just type:

rake rails:unfreeze

Next, install the acts_as_taggable plugin:

script/plugin install acts_as_taggable</pre>

Now create a migration to add two tables to store the tagging information:

<pre>script/generate migration add_tag_support</pre>

Insert the following:

<pre> class AddTagSupport < ActiveRecord::Migration def self.up #Table for your Tags create_table :tags do |t| t.column :name, :string end create_table :taggings do |t| t.column :tag_id, :integer #id of tagged object t.column :taggable_id, :integer #type of object tagged t.column :taggable_type, :string end # Index your tags/taggings add_index :tags, :name add_index :taggings, [:tag_id, :taggable_id, :taggable_type] end

def self.down drop_table :taggings drop_table :tags end

end



Run Rake to add the tables to the database.

rake db:migrate



An example:

First create a model that you want to tag. In this example books. So we generate a database table books and generate the model:

script/generate model Book</pre>

Next we add the acts_as_taggable line to the modelfile (book.rb):


 class Book < ActiveRecord::Base
  acts_as_taggable
 end

Finally we should have created the tags and taggings tables so we can start tagging:


 mybook = Book.new
 mybook.tag_with('red library book')
 mybook.save
 mybook.tag_list #gives back 'red library book'
 Book.find_tagged_with('library') #gives your Book
</pre>

This generates three tags with the names ‘red’, ‘library’ and ‘book’ in the tag table. Next it creates rows in the taggings table with the taggable_type set to ‘Book’ and the tag_id set to the corresponding tag in the tag table. The taggable_id is set to the id of the book in your books table.

Nice huh?

ALSO: The View (forms)
<pre> <%= text_field_tag 'tag_list', @item.tags.collect{|t| t.name}.join(" ") %> </pre>

if you are using the alias below, you can use this in the view instead and then you don’t have to do the controller-fu below.

<pre> <%= text_field 'item', 'tag_list' %> </pre>

AND The Controller (if using the default generated scaffolding).
For example in say books_controller.rb add the following to your ‘update’ and ‘create’ methods:
<pre> @book.tag_with(params[:tag_list])


- David Andrew Thompson

Question:
If tag_with was named tag_list= it would just work in most controllers/views with normal @model.update(params[:model]) calls, instead of having to do it manually like above.

Is there a reason why its not called tag_list=, or that the method isn’t aliased for this purpose?

If anyone wants to do this, just add:

alias tag_list= tag_with

under the tag_with method in acts_as_taggable.rb

-Nate K.

AND The Fixtures. tags.yml looks like this:


big:
  id: 1
  name: Big
  
small:
  id: 2
  name: Small

taggings.yml looks like this:


big_elephant:
  id: 1
  tag_id: 1
  taggable_id: 50 # Elephant is an Animal record with id 50
  taggable_type: Animal

small_beer:
id: 1
tag_id: 1
taggable_id: 20 # Beer is a Beverage record with id 20
taggable_type: Beverage

Note:
This post has some useful information about how the code in /vendor/plugins/acts_as_taggable/lib works.

Note:
I was having issues with the tag.collect putting information in single quotes and on an update that information begin submitted to the database as “’test” “series’” instead of “test series” so I corrected line 52:


 tags.collect { |tag| tag.name.include?(" ") ? "'#{tag.name}'" : tag.name }.join(" ")
</pre>

so that the tags will be in double quotes and insert into the database correctly:


 tags.collect { |tag| tag.name.include?(" ") ? '"' +"#{tag.name}" + '"' : tag.name }.join(" ")

Note:
I needed the tags_count method, so I put “my own” in module SingletonMethods (in acts_as_taggable.rb), like this:


 def tags_count(options)
   sql = "SELECT  tags.id AS id, tags.name AS name, COUNT(*) AS count FROM tags, taggings, #{table_name} "
   sql << "WHERE taggings.taggable_id = #{table_name}.#{primary_key} AND taggings.tag_id = tags.id "
   sql << "AND #{sanitize_sql(options[:conditions])} " if options[:conditions]
   sql << "GROUP BY tags.name "
   sql << "HAVING count #{options[:count]} " if options[:count]
   sql << "ORDER BY #{options[:order]} " if options[:order]
   sql << "LIMIT #{options[:limit]} " if options[:limit]
   find_by_sql(sql)
end


For instance:

@tags = Post.tags_count :conditions => "posts.posttype = 'public'", :order => 'count DESC'

Note: *
The tag_with is destructive, it deletes all previous tags which is not always what you want on an edit. I added the following method: EO


  def add_tags(list)          
    Tag.transaction do
      Tag.parse(list).each do |name|
        if acts_as_taggable_options[:from]
          send(acts_as_taggable_options[:from]).tags.find_or_create_by_name(name).on(self)
        else
          Tag.find_or_create_by_name(name).on(self)
        end
      end
    end
  end      
</pre>
This should be added to acts_as_taggable.rb
*Further note:
After much confusion, it was finally noted that add_tags was a deprecated association method (?!). Thus, no edits to it were working… Change the name of the above to add_tag, add_tag_list, or something similar, and all will be well.

another addition to the above:
In order to prevent multiple additions to taggable on the same tag change this:

 
  Tag.find_or_create_by_name(name).on(self)

To

 t = Tag.find_or_create_by_name(name)
 t.on(self) unless self.tags.include? t


*Note: *
ClassMethod for filtering tags by the Class of the item being tagged. This lets you filter tag to those available for a certain class. Used to assign roles to a users in a system.
It is an ugly hack as it should be an instance method that uses self.class to find out the jind od the class it is after.


def class_tagged(class_type)
  @taggings = Tagging.find_all_by_taggable_type(class_type)
  @tags = Hash.new
  @taggings.each do |tagging|
    @tags[tagging.tag.name]= tagging.tag
  end
  return @tags.values
end
</pre>

*… response to above? *
The above can be accomplished with a new ClassMethod. The following allows you to retrieve all unique tags for a given Class (as an array). I am guessing you would like to have this capability if you had multiple models that were acts_as_taggable, and wanted to list the tags for only a certain model. At the time of writing this my application only has one model, so I cannot test with multiple models. -markG


-- acts_as_taggable.rb 
-
- (in module ClassMethods) —-

def tag_list
@taggings = Tagging.find_all_by_taggable_type(ActiveRecord::Base.send(:class_name_of_active_record_descendant, self).to_s)
return @taggings.collect { |tagging| tagging.tag.name }.uniq
end

—- usage —-
Mymodel.tag_list

A Better Solution to Get Tags by Model?
Rather than implementing a whole new method, a line added to the existing self.tag method in tag.rb allows you to retrieve tags by model name.

By adding the following line between lines 4 and 5:


query << " AND taggings.taggable_type = #{options[:taggable_type]}'" if options[:taggable_type] != nil

Our method will now look like this:


  def self.tags(options = {})
    query = "select tags.id, name, count(*) as count"
    query << " from taggings, tags"
    query << " where tags.id = tag_id"
    query << " AND taggings.taggable_type = #{options[:taggable_type]}'" if options[:taggable_type] != nil
    query << " group by tag_id"
    query << " order by #{options[:order]}" if options[:order] != nil
    query << " limit #{options[:limit]}" if options[:limit] != nil
    tags = Tag.find_by_sql(query)
  end

We can call this as so:

@tags = Tag.tags(:order => "name", :taggable_type => "post")

I’ve fully documented this in my article, Modifiy Acts_As_Taggable to Return Tags By Model, including both this version and a version that follows Rails conventions more closely.

Note
User-specific acts_as_taggable functionality

Bath and Shower
Fragrance
Gift Sets
Hair Care
Makeup
Men’s Grooming
Shaving and Hair Removal
Skin Care
Tools and Accessories

Baby Apparel
Baby Bathing & Skin Care
Baby Bedding
Baby Car Seats
Baby Diapering
Baby Feeding
For Moms
Baby Furniture
Baby Gear
Baby Gifts
Baby Health & Baby Care
Nursery Décor
Potty Training
Baby Safety
Baby Strollers

Books – Business & Investing
Books – Children’s Books
Books – Comics & Graphic Novels
Books – Computers & Internet
Books – Cooking, Food & Wine
Books – Entertainment
Books – Gay & Lesbian
Books – Health, Mind & Body
Books – History
Books – Home & Garden
Books – Law
Books – Literature & Fiction
Books – Medicine
Books – Mystery & Thrillers
Books – Nonfiction
Books – Outdoors & Nature
Books – Parenting & Families
Books – Professional & Technical
Books – Reference
Books – Religion & Spirituality
Books – Romance
Books – Science
Books – Science Fiction & Fantasy
Books – Sports
Books – Teens
Books – Travel

Camera & Photo – Accessories
Camera & Photo – Camcorders
Camera & Photo – Digital Cameras
Camera & Photo – Film Cameras
Camera & Photo – Optics
Camera & Photo – Printers & Scanners

Health & Personal Care – Baby & Child Care
Health & Personal Care – Food & Snacks
Health & Personal Care – Health & Personal Care Outlet Store
Health & Personal Care – Health Care
Health & Personal Care – House Supplies
Health & Personal Care – Nutrition & Fitness
Health & Personal Care – Personal Care
Health & Personal Care – Sexual Wellness

Computers – Computer Add-Ons
Computers – Desktops
Computers – Handhelds & PDAs
Computers – Notebooks

Electronics – Accessories & Supplies
Electronics – Audio & Video
Electronics – Camera & Photo
Electronics – Car Electronics
Electronics – Computers & Add-Ons
Electronics – GPS & Navigation
Electronics – Home Automation & Security
Electronics – Office Electronics
Electronics – Service & Replacement Plans

Gourmet Food – Appetizers & Hors d’oeuvres
Gourmet Food – Baking Supplies
Gourmet Food – Beverages
Gourmet Food – Bread
Gourmet Food – Breakfast Foods
Gourmet Food – Candy
Gourmet Food – Cheese
Gourmet Food – Chocolate
Gourmet Food – Coffee & Tea
Gourmet Food – Cookies
Gourmet Food – Dairy Foods & Eggs
Gourmet Food – Desserts
Gourmet Food – Fruits & Vegetables
Gourmet Food – Gourmet Gifts
Gourmet Food – Jams, Jellies & Preserves
Gourmet Food – Meat, Game & Pâtés
Gourmet Food – Oils, Vinegars & Salad Dressings
Gourmet Food – Pasta, Beans, Grains & Rice
Gourmet Food – Prepared Meals
Gourmet Food – Salsas & Condiments
Gourmet Food – Seafood & Caviar
Gourmet Food – Seasonings, Herbs & Spices
Gourmet Food – Snack Food
Gourmet Food – Soups & Stocks

Grocery – Appetizers & Hors D’Oeuvres
Grocery – Baking Supplies
Grocery – Beverages
Grocery – Boxed Meals & Side Dishes
Grocery – Breads
Grocery – Breakfast Foods
Grocery – Canned & Packaged Goods
Grocery – Coffee, Tea & Cocoa
Grocery – Condiments, Sauces & Spreads
Grocery – Dairy & Eggs
Grocery – Desserts & Pastries
Grocery – Fruits & Vegetables
Grocery – Health & Family
Grocery – Herbs, Spices & Seasonings
Grocery – Household Supplies
Grocery – Meats
Grocery – Pasta & Grains
Grocery – Pet Supplies
Grocery – Seafood
Grocery – Snacks, Cookies & Candy

Home & Garden – Backyard Birding
Home & Garden – Bar Tools & Glasses
Home & Garden – Bedding & Bath
Home & Garden – Coffee, Tea & Espresso
Home & Garden – Cook’s Tools & Gadgets
Home & Garden – Cookware & Baking
Home & Garden – Cutlery
Home & Garden – Fresh Flowers & Indoor Plants
Home & Garden – Furniture & Décor
Home & Garden – Gardening Tools
Home & Garden – Grills, Smokers & Outdoor Cooking
Home & Garden – Heating & Lighting
Home & Garden – Kitchen & Table Linens
Home & Garden – Large Appliances
Home & Garden – Leisure & Fitness
Home & Garden – Outdoor Décor
Home & Garden – Patio Furniture
Home & Garden – Pest Control
Home & Garden – Pet Supplies
Home & Garden – Plants & Planting
Home & Garden – Small Appliances
Home & Garden – Tableware
Home & Garden – Vacuums, Cleaning & Storage
Home & Garden – Weather Instruments
Home & Garden – Wine Accessories

Industrial & Scientific – Adhesive Tapes
Industrial & Scientific – Fasteners
Industrial & Scientific – Industrial Abrasives
Industrial & Scientific – Industrial Adhesives
Industrial & Scientific – Industrial Cutting Tools
Industrial & Scientific – Industrial Hoses
Industrial & Scientific – Material Handling Equipment
Industrial & Scientific – Mechanical Components
Industrial & Scientific – Precision Measurement Products
Industrial & Scientific – Raw Materials

Jewelry – Accessories
Jewelry – Body Jewelry
Jewelry – Bracelets
Jewelry – Brooches & Pins
Jewelry – Charms
Jewelry – Children’s Jewelry
Jewelry – Earrings
Jewelry – Engagement
Jewelry – Jewelry Sets
Jewelry – Men’s Jewelry
Jewelry – Necklaces & Pendants
Jewelry – Religious Jewelry
Jewelry – Rings
Jewelry – Wedding & Anniversary

Kindle Store – Advice & How-to
Kindle Store – Arts & Entertainment
Kindle Store – Biographies & Memoirs
Kindle Store – Business & Investing
Kindle Store – Children’s Chapter Books
Kindle Store – Computers & Internet
Kindle Store – Fantasy
Kindle Store – Fiction
Kindle Store – History
Kindle Store – Humor
Kindle Store – Lifestyle & Home
Kindle Store – Literary Fiction
Kindle Store – Mystery & Thrillers
Kindle Store – Nonfiction
Kindle Store – Parenting & Families
Kindle Store – Politics & Current Events
Kindle Store – Reference
Kindle Store – Religion & Spirituality
Kindle Store – Romance
Kindle Store – Science
Kindle Store – Science Fiction
Kindle Store – Sports
Kindle Store – Travel

Kitchen & Housewares – Bar Tools & Glasses
Kitchen & Housewares – Coffee, Tea & Espresso
Kitchen & Housewares – Cook’s Tools & Gadgets
Kitchen & Housewares – Cookware & Baking
Kitchen & Housewares – Cutlery
Kitchen & Housewares – Dining Room Furniture
Kitchen & Housewares – Kitchen & Table Linens
Kitchen & Housewares – Kitchen Furniture
Kitchen & Housewares – Small Appliances
Kitchen & Housewares – Storage & Organization
Kitchen & Housewares – Tableware
Kitchen & Housewares – Wine Accessories

Magazine Subscriptions – Arts & Crafts
Magazine Subscriptions – Automotive
Magazine Subscriptions – Bridal
Magazine Subscriptions – Business & Finance
Magazine Subscriptions – Children’s
Magazine Subscriptions – Computer & Internet
Magazine Subscriptions – Electronics & Audio
Magazine Subscriptions – Entertainment
Magazine Subscriptions – Family & Parenting
Magazine Subscriptions – Fashion & Style
Magazine Subscriptions – Food & Gourmet
Magazine Subscriptions – Games & Hobbies
Magazine Subscriptions – Gay & Lesbian
Magazine Subscriptions – Health & Fitness
Magazine Subscriptions – History
Magazine Subscriptions – Home & Garden
Magazine Subscriptions – International
Magazine Subscriptions – Lifestyle & Cultures
Magazine Subscriptions – Literary
Magazine Subscriptions – Men’s Interest
Magazine Subscriptions – Music
Magazine Subscriptions – News & Politics
Magazine Subscriptions – Pets
Magazine Subscriptions – Religion & Spirituality
Magazine Subscriptions – Science & Nature
Magazine Subscriptions – Sports & Leisure
Magazine Subscriptions – Teens
Magazine Subscriptions – Travel & Regional
Magazine Subscriptions – Women’s Interest

Miscellaneous – Aircraft
Miscellaneous – Antiques
Miscellaneous – Coins
Miscellaneous – Collectibles
Miscellaneous – General
Miscellaneous – Other Products
Miscellaneous – Scientific Supplies
Miscellaneous – Stamps
Miscellaneous – Vehicles
Miscellaneous – Watercraft

MP3 Downloads – MP3 Albums
MP3 Downloads – MP3 Songs

Music – Alternative Rock
Music – Blues
Music – Broadway & Vocalists
Music – Children’s Music
Music – Christian & Gospel
Music – Classic Rock
Music – Classical
Music – Country
Music – Dance & DJ
Music – Folk
Music – Hard Rock & Metal
Music – International
Music – Jazz
Music – Latin Music
Music – Miscellaneous
Music – New Age
Music – Pop
Music – R&B
Music – Rap & Hip-Hop
Music – Rock
Music – Soundtracks

Classical Music – Ballads
Classical Music – Canons
Classical Music – Concertos
Classical Music – Etudes
Classical Music – Fantasies
Classical Music – Fugues
Classical Music – Improvisation
Classical Music – Inventions
Classical Music – Lullabies & Berceuse
Classical Music – Oratorio
Classical Music – Preludes
Classical Music – Requiems, Elegies & Tombeau
Classical Music – Rondos
Classical Music – Scherzo
Classical Music – Serenades & Divertimentos
Classical Music – Short Forms
Classical Music – Sonatas
Classical Music – Suites
Classical Music – Symphonies
Classical Music – Theatrical, Incidental & Program Music
Classical Music – Toccatas
Classical Music – Variations

Musical Instruments – Band & Orchestra
Musical Instruments – Bass Guitars
Musical Instruments – DJ, Electronic Music & Karaoke
Musical Instruments – Drums & Percussion
Musical Instruments – Folk & World Instruments
Musical Instruments – Guitars
Musical Instruments – Instrument Accessories
Musical Instruments – Keyboards
Musical Instruments – Live Sound & Stage
Musical Instruments – Recording Equipment

Office Products – Business Presentation Supplies
Office Products – Educational Supplies
Office Products – Mailroom Supplies
Office Products – Office Furniture & Accessories
Office Products – Office Lighting
Office Products – Office Supplies

Cell Phones & Service – All
Cell Phones & Service – Bluetooth
Cell Phones & Service – Camera
Cell Phones & Service – E-mail
Cell Phones & Service – Flip
Cell Phones & Service – Kid’s
Cell Phones & Service – Mobile Broadband Cards
Cell Phones & Service – MP3
Cell Phones & Service – PDA
Cell Phones & Service – Prepaid
Cell Phones & Service – Video
Cell Phones & Service – Wi-Fi

Software – Business & Office
Software – Children’s Software
Software – Education & Reference
Software – Graphics
Software – Home & Hobbies
Software – Language & Travel
Software – Linux
Software – Macintosh
Software – Networking
Software – Operating Systems
Software – Outlet
Software – Personal Finance
Software – Programming
Software – Software for Handhelds
Software – Utilities
Software – Video & Music
Software – Web Development

Sports & Outdoors – Accessories
Sports & Outdoors – Airsoft
Sports & Outdoors – Apparel
Sports & Outdoors – Archery
Sports & Outdoors – Badminton
Sports & Outdoors – Ballet & Dance
Sports & Outdoors – Baseball
Sports & Outdoors – Basketball
Sports & Outdoors – Boating
Sports & Outdoors – Bowling
Sports & Outdoors – Boxing
Sports & Outdoors – Camping & Hiking
Sports & Outdoors – Cheerleading
Sports & Outdoors – Climbing
Sports & Outdoors – Crew
Sports & Outdoors – Cricket
Sports & Outdoors – Curling
Sports & Outdoors – Cycling & Wheel Sports
Sports & Outdoors – Disc Sports
Sports & Outdoors – Diving
Sports & Outdoors – Dog Sports
Sports & Outdoors – Equestrian Sports
Sports & Outdoors – Exercise & Fitness
Sports & Outdoors – Fan Shop