Plugins - acts_as_taggable_redux

StarAdd to favorites

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

  New Item

  <% form_for(:item, @item) do |f| -%>

    <%= error_message_for :item %>

    Tags: <%= f.text_field :tag_list -%>

    <%= submit_tag "Save" -%>

  <% end -%>

if you want users to own taggings change the tags line to this

  Tags: <%= 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

  New Item

  <% form_for(:item, @item, :html => { :method => :post }) do |f| -%>

    <%= error_messages_for :item %>

    Tags: <%= 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 %>

Copyright © 2007 monki(Wesley Beary), released under the MIT license

monki

http://geemus.devjavu.com/

http://svn.devjavu.com/geemus/rails/plugins/acts_as_taggable_redux

Rails' (MIT)

  • Currently 4.6/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Model

Tags

Comments

Add a comment
jsyrjala 18 Sep 2008

It seems that the svn repository is not updated. There seems to be an updated repository in github: http://github.com/monki/actsas_taggableredux/

Matt V 27 Jul 2008

to get the migration generator to work with rails 2.1, I had to change tasks/actsas_taggabletasks.rake and add

require 'environment'

before require 'rails_generator'

hat tip to: http://d.hatena.ne.jp/kusakari/20080721/1216634680

Hari 25 Jan 2008

How can I generate a tag cloud per user? Is it possible?

Thanks

ben 17 Jan 2008

Or - if the moderator prefers - here are changes I made in a blog post http://mudabone.com/aietc/?p=762

ben 17 Jan 2008

Thanks for the plugin! A few additions is it helps anyone:

1) Need to add "acts_as_taggable" to model being tagged (items in your example)

2) Modified findtaggedwith to work with will_paginate plugin

    def find_tagged_with(tags, options = {}, page = 1, per_page = 10)
      options.assert_valid_keys([:match, :user])

      tags = Tag.parse(tags)
      return [] if tags.empty?

      group = &quot;#{table_name}_taggings.taggable_id HAVING COUNT(#{table_name}_taggings.taggable_id) = #{tags.size}&quot; if options[:match] == :all
      conditions = sanitize_sql([&quot;#{table_name}_tags.name IN (?)&quot;, tags])
      conditions += sanitize_sql([&quot; AND #{table_name}_taggings.user_id = ?&quot;, options[:user]]) if options[:user]

      paginate(:all, 
        { 
          :select =&gt;  &quot;DISTINCT #{table_name}.*&quot;,
          :joins  =&gt;  &quot;LEFT OUTER JOIN taggings #{table_name}_taggings ON #{table_name}_taggings.taggable_id = #{table_name}.#{primary_key} AND #{table_name}_taggings.taggable_type = '#{name}' &quot; +
                      &quot;LEFT OUTER JOIN tags #{table_name}_tags ON #{table_name}_tags.id = #{table_name}_taggings.tag_id&quot;,
          :conditions =&gt; conditions,
          :group  =&gt;  group,
          :page =&gt; page,
          :per_page =&gt; per_page
        })
    end

3) Modified helper for better seo - added this to ActsAsTaggableHelper

def tag_url(tag) "/tags/#{tag.name}" end

4) Added delicious styled tagging form helper to do this: a) add this to ActsAsTaggableHelper def delicious_tags(obj, f) res = %(<br/><b>Tags:</b> #{f.textfield :taglist}) res << %(<div style="border:solid 1px; margin:10px; padding:10px;">) res << spacedtagsdelicious(obj) res << "</div>" return res end

def spacedtagsdelicious(obj) res = [] Tag.find(:all, :order => "name").each do |tag| link = %(javascript:swaptag('#{tag.name}','#{obj.class.name.tableize.singularize}tag_list')) res << link_to(tag.name, link) end return res.join(" ") end

b) include tags.js

//modified selections from http://del.icio.us/ui/static/post.js?v=3o3

tag_delimitor = " "

function swap_tag(tag,elem) { swap_tag(tag,elem,true) } function swaptag(tag,elem,changecase){ if (change_case == true) { tag = trim(tag).toLowerCase(); } else { tag = trim(tag) } tags = document.getElementById(elem) var tagArray = trim(tags.value).split(tag_delimitor) var present = false; if (trim(tagArray[0]) == '') tagArray.splice(0,1); for (t=0; t<tagArray.length; t++) { if (trim(tagArray[t]).toLowerCase() == tag || (change_case == false && trim(tagArray[t]) == tag) ) { tagArray.splice(t,1); present=true; t-=1;
} } if (!present) { tagArray.push(tag); } var content = tagArray.join(tag_delimitor) //tags.value = (content.length > 1) ? content + ', ' : content tags.value = content; //focusTo(tags) }

function trim(str) { return str.replace(/^\s|\s$/g,""); }

c) Call from your form like

            &lt;%=delicious_tags (@blog_entry, f)%&gt;

4) Also added a simple "spaced tag" helper to ActsAsTaggableHelper to put tags in blog footers (or whatever)

def spaced_tags(obj) res = [] obj.tags.each do |tag| res << link_to_tag(tag) end return res.join(" ") end

Hari 7 Sep 2007

I would like to search Items by tags,

So I created a TagsController,

so that on a request like /tags/23 from the tag cloud, I can create a show method in TagsController that can do the findtaggedwith and return the Items.

How do I make this happen? As such, I cannot call findtaggedwith from the TagsController.

TIA

Sat 1 Sep 2007

How does one display a tagcloud for the currentuser?

Thanks Sat

monki 23 Aug 2007

I think script/plugin install --force would certainly get you the newest version. You shouldn't need to run db:migrate again if you ran it before. Theoretically the user specific stuff was all there before in the database, just some of the functions weren't working quite right for it. After script/plugin you should be good to go, feel free to email me if it gives you problems and I will get the fixed up as soon as I can. Thanks for using the plugin, hope it is helpful.

Sat 15 Aug 2007

I see that there is a new version that can handle user specific tags. How do I upgrade? Run script/plugin install --force? Is there any need to run db:migrate again when upgrading?

TIA for your help

aroedl 30 Jul 2007

@Sat:

Make sure that your controller is called "Tags" and not "Tag" and that you have

map.resources :tags

(not map.resource) in routes.rb.

monki 21 Jul 2007

I haven't provided an easy option for switching the token delimiter at this point I'm afraid. It should be pretty easy to switch. The portion in question is in actsas_taggableredux/lib/tags.rb in the parse function.
To prevent commas being replaced by spaces, comment out: list.gsub!(/,/, " ")

Then change the split around whitespace: tag_names.concat(list.split(/\s/))

To a split around commas: tag_names.concat(list.split(/,/))

And you should be set. I may have to add more explicit options for this kind of thing in the future.

Chris 18 Jul 2007

It looks like it parses the tags by spaces versus commas, is there a way to switch that behavior so that it looks at the commas and groups words together?

monki 11 Jul 2007

I would say the issue is probably in your ItemsController, I'd need to see the code for that. Feel free to send me an email and I can probably help sort you out.

begin 10 Jul 2007
how i can integrate tags with an Item model and a user model? I have it working with Rails 1.2.3 using: i add this to my user model: acts_as_tagger but give me an error when i create item: NoMethodError in ItemsController#create undefined method `tag_list=' for #<Item:0x47fe848> then i add "acts_as_taggable" to my item model, ArgumentError in ItemsController#create Wrong number of arguments (1 for 0) new.rhtml: <b>Tags:</b> <%= f.text_field :tag_list, :value => @item.tag_list(current_user) -%> <%= f.hidden_field :user_id, :value => current_user.id -%> I am using acts_as_authenticated, help me please.
Sat 16 Jun 2007

Thanks Thurin, that worked for me too.

Is there a way to filter the tag cloud for the current user? I am using acts_as_authenticated, so I can identify the current user any time.

Thanks in advance for all the help

monki 26 May 2007

I suppose you wouldn't have to have a tags controller, but the helpers are written with that assumption. (Thanks for pointing it out, I'll add it to the README).

thurin 22 May 2007

I have it working with Rails 1.2.3 using:

map.resources :tags

in my routes.rb. The only issue i see is that when clicking a tag either from the cloud of from the tag list on an item i get the following error:

"uninitialized constant TagsController"

I assume I need to write a TagsController to handle looking for items that match the tag?

monki 17 May 2007

That means RESTful routes aren't getting setup properly. You will need EDGE rails, and a proper routes.rb

For edge, the easy way: rake rails:freeze:edge Or you can use svn/externals (google for 'edge rails svn')

Then make sure your routes.rb includes: map.resource :tags

Sat 17 May 2007
I am trying to display the tag cloud in a view. This view is for a model that is taggable. Here is the error message as requested: undefined method `tag_url' for #<#<Class:0x483cc9c>:0x483cc74> Extracted source (around line #40): 37: <%= submit_tag 'Save' %> 38: </fieldset> 39: <% end -%> 40: <%= tag_cloud %> Thanks Sat
monki 16 May 2007

Could you provide the whole error message? Feel free to post it or email it to me and I will see what I can do.

Sat 16 May 2007

I found this plugin to be much better than actsas_taggable and actsastaggableon_steroids. It also has the DB optmization of yet another plugin out there included.

Monki, thanks for putting this out there. I just had one glitch, the tag_cloud method is not working in my view. It gives me a method not found error.

Can you point out what is wrong? BTW I am a RoR noob.

Thanks Sat

Search Plugins

Query syntax

Plugins by Category

Sponsors

Rails Kits: Get Code. Get Moving.

Have a comment?