diff --git a/app/controllers/aspects_controller.rb b/app/controllers/aspects_controller.rb
index ec8af115dc7acf7e21e521f885a7f34e713cefc4..c47257a1657f19a86cfd9cb8ad8b25971365b2e4 100644
--- a/app/controllers/aspects_controller.rb
+++ b/app/controllers/aspects_controller.rb
@@ -9,6 +9,9 @@ class AspectsController < ApplicationController
 
   respond_to :html, :js
   respond_to :json, :only => [:show, :create]
+  
+  helper_method :tags, :tag_followings
+  helper_method :all_aspects_selected?
 
   def index
     if params[:a_ids]
@@ -158,11 +161,23 @@ class AspectsController < ApplicationController
     params[:max_time] ||= Time.now + 1
   end
 
-  helper_method :all_aspects_selected?
   def all_aspects_selected?
     @aspect == :all
   end
 
+  def tag_followings
+    if current_user
+      if @tag_followings == nil
+        @tag_followings = current_user.tag_followings
+      end
+      @tag_followings
+    end
+  end
+
+  def tags
+    @tags ||= current_user.followed_tags
+  end
+
   private
   def save_sort_order
     if params[:sort_order].present?
diff --git a/app/controllers/tag_followings_controller.rb b/app/controllers/tag_followings_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2883f501de9759ae50424113712e2ef1e1f6823a
--- /dev/null
+++ b/app/controllers/tag_followings_controller.rb
@@ -0,0 +1,32 @@
+class TagFollowingsController < ApplicationController
+  before_filter :authenticate_user!
+
+  # POST /tag_followings
+  # POST /tag_followings.xml
+  def create
+    @tag = ActsAsTaggableOn::Tag.find_or_create_by_name(params[:name])
+    @tag_following = current_user.tag_followings.new(:tag_id => @tag.id)
+
+    if @tag_following.save
+      flash[:notice] = I18n.t('tag_followings.create.success', :name => params[:name]) 
+    else
+      flash[:error] = I18n.t('tag_followings.create.failure', :name => params[:name])
+    end
+
+    redirect_to tag_path(:name => params[:name])
+  end
+
+  # DELETE /tag_followings/1
+  # DELETE /tag_followings/1.xml
+  def destroy
+    @tag = ActsAsTaggableOn::Tag.find_by_name(params[:name])
+    @tag_following = current_user.tag_followings.where(:tag_id => @tag.id).first
+    if @tag_following && @tag_following.destroy
+      flash[:notice] = I18n.t('tag_followings.destroy.success', :name => params[:name])
+    else
+      flash[:error] = I18n.t('tag_followings.destroy.failure', :name => params[:name])
+    end
+
+    redirect_to tag_path(:name => params[:name])
+  end
+end
diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb
index 1459148567efb17e8043e6e5f5692883812e5a5b..fe9e18e1f10e48b959298bddcdc35df3421de8fe 100644
--- a/app/controllers/tags_controller.rb
+++ b/app/controllers/tags_controller.rb
@@ -8,6 +8,8 @@ class TagsController < ApplicationController
   skip_before_filter :set_grammatical_gender
   before_filter :ensure_page, :only => :show
 
+  helper_method :tag_followed?
+
   respond_to :html, :only => [:show]
   respond_to :json, :only => [:index]
 
@@ -41,8 +43,10 @@ class TagsController < ApplicationController
   def show
     @aspect = :tag
     if current_user
-      @posts = StatusMessage.joins(:contacts).where(:pending => false).where(
-        Contact.arel_table[:user_id].eq(current_user.id).or(
+      @posts = StatusMessage.
+        joins("LEFT OUTER JOIN post_visibilities ON post_visibilities.post_id = posts.id").
+        joins("LEFT OUTER JOIN contacts ON contacts.id = post_visibilities.contact_id").
+        where(Contact.arel_table[:user_id].eq(current_user.id).or(
           StatusMessage.arel_table[:public].eq(true).or(
             StatusMessage.arel_table[:author_id].eq(current_user.person.id)
           )
@@ -55,7 +59,6 @@ class TagsController < ApplicationController
 
     max_time = params[:max_time] ? Time.at(params[:max_time].to_i) : Time.now
     @posts = @posts.where(StatusMessage.arel_table[:created_at].lt(max_time))
-
     @posts = @posts.includes(:comments, :photos).order('posts.created_at DESC').limit(15)
 
     @posts = PostsFake.new(@posts)
@@ -69,4 +72,11 @@ class TagsController < ApplicationController
       @people_count = Person.where(:id => profiles.map{|p| p.person_id}).count
     end
   end
+
+ def tag_followed?
+   if @tag_followed.nil?
+     @tag_followed = TagFollowing.joins(:tag).where(:tags => {:name => params[:name]}, :user_id => current_user.id).exists? #,    
+   end
+   @tag_followed
+ end
 end
diff --git a/app/helpers/tag_followings_helper.rb b/app/helpers/tag_followings_helper.rb
new file mode 100644
index 0000000000000000000000000000000000000000..03bd57800813e883c2e56f5b9557f31c5ecb17a5
--- /dev/null
+++ b/app/helpers/tag_followings_helper.rb
@@ -0,0 +1,2 @@
+module TagFollowingsHelper
+end
diff --git a/app/models/tag_following.rb b/app/models/tag_following.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6fd07c0eff12b1a907bd0d6a290c61166b24d665
--- /dev/null
+++ b/app/models/tag_following.rb
@@ -0,0 +1,6 @@
+class TagFollowing < ActiveRecord::Base
+  belongs_to :user
+  belongs_to :tag, :class_name => "ActsAsTaggableOn::Tag"
+
+  validates_uniqueness_of :tag_id, :scope => :user_id
+end
diff --git a/app/models/user.rb b/app/models/user.rb
index 0bab1c58ead984b722c606128cdeafe22a2242e3..d93087837189cde29c55f399b7ca3f43b779f6d9 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -39,6 +39,8 @@ class User < ActiveRecord::Base
   has_many :contact_people, :through => :contacts, :source => :person
   has_many :services, :dependent => :destroy
   has_many :user_preferences, :dependent => :destroy
+  has_many :tag_followings, :dependent => :destroy
+  has_many :followed_tags, :through => :tag_followings, :source => :tag
 
   has_many :authorizations, :class_name => 'OAuth2::Provider::Models::ActiveRecord::Authorization', :foreign_key => :resource_owner_id
   has_many :applications, :through => :authorizations, :source => :client
diff --git a/app/views/aspects/index.html.haml b/app/views/aspects/index.html.haml
index 26824860dbe499eb7dddcd90d0ce2ff3ec816f55..955be317670b245338858f2b30065e9c54ce2790 100644
--- a/app/views/aspects/index.html.haml
+++ b/app/views/aspects/index.html.haml
@@ -15,6 +15,17 @@
   .section
     = render 'aspects/aspect_listings'
 
+  .section
+    %ul.left_nav
+      %li
+        %div.root_element
+          = t('aspects.index.tags_following')
+
+        %ul.sub_nav
+          - for tg in tags
+            %li
+              = link_to "##{tg.name}", tag_path(:name => tg.name), :class => "tag_selector"
+
 .span-13.append-1.prepend-5
   #aspect_stream_container.stream_container
     = render 'aspect_stream',
diff --git a/app/views/tags/show.haml b/app/views/tags/show.haml
index ee681076c145ac0343ce04a6763b5f54b1c8c422..7fe40c9bbd8d0d2dfa96e65e8c9839b73c662b03 100644
--- a/app/views/tags/show.haml
+++ b/app/views/tags/show.haml
@@ -2,6 +2,7 @@
 -#   licensed under the Affero General Public License version 3 or later.  See
 -#   the COPYRIGHT file.
 
+
 - content_for :page_title do
   - if params[:name]
     = "##{params[:name]}"
@@ -11,29 +12,48 @@
 - content_for :head do
   = include_javascripts :home
   :javascript
-    $(".people_stream .pagination a").live("click", function() {
-      $.getScript(this.href);
-      return false;
+    $(document).ready(function(){
+      $(".button.tag_following").hover(function(){
+        $this = $(this);
+        $this.removeClass("in_aspects");
+        $this.val("#{t('.stop_following', :tag => params[:name])}");
+      },
+      function(){
+        $this = $(this);
+        $this.addClass("in_aspects");
+        $this.val("#{t('.following', :tag => params[:name])}");
+      });
     });
+
 - content_for :body_class do
   = "tags_show"
 
-.span-24.last
-  %h1.tag
-    = "##{params[:name]}"
-
-.span-13
-  #main_stream.stream
-    - if @posts.length > 0
-      = render 'shared/stream', :posts => @posts
-      #pagination
-        =link_to(t('more'), next_page_path, :class => 'paginate')
-    - else
-      = t('.nobody_talking', :tag => "##{params[:name]}")
-
-.prepend-2.span-9.last
+.span-6
   %h3
     = t('people', :count => @people_count)
 
   .side_stream.stream
     = render :partial => 'people/index', :locals => {:people => @people}
+
+.span-15.last
+  .stream_container
+    #author_info
+      - if user_signed_in? && current_user.person != @person
+        .right
+          - unless tag_followed?
+            = button_to t('.follow', :tag => params[:name]), tag_tag_followings_path(:name => params[:name]), :method => :post,   :class => 'button take_action'
+          - else
+            = button_to t('.following', :tag => params[:name]), tag_tag_followings_path(:name => params[:name]), :method => :delete,   :class => 'button red_on_hover tag_following in_aspects take_action'
+      %h2
+        = "##{params[:name]}"
+
+    %hr
+
+    #main_stream.stream
+      - if @posts.length > 0
+        = render 'shared/stream', :posts => @posts
+        #pagination
+          =link_to(t('more'), next_page_path, :class => 'paginate')
+      - else
+        = t('.nobody_talking', :tag => "##{params[:name]}")
+
diff --git a/config/locales/diaspora/en.yml b/config/locales/diaspora/en.yml
index dd352603bc0db7761543d10a6d95ea03a096616f..b8a609eb0e3586156964f6d3aaf70e156d86a991 100644
--- a/config/locales/diaspora/en.yml
+++ b/config/locales/diaspora/en.yml
@@ -146,6 +146,7 @@ en:
       work: "Work"
     index: 
       your_aspects: "Your Aspects"
+      tags_following: "Followed Tags"
       handle_explanation: "This is your diaspora id. Like an email address, you can give this to people to reach you."
       no_contacts: "No contacts"
       post_a_message: "post a message >>"
@@ -697,6 +698,17 @@ en:
       posts_tagged_with: "Posts tagged with #%{tag}"
       nobody_talking: "Nobody is talking about %{tag} yet."
       people_tagged_with: "People tagged with %{tag}"
+      follow: "Follow #%{tag}"
+      following: "Following #%{tag}"
+      stop_following: "Stop Following #%{tag}"
+
+  tag_followings:
+    create:
+      success: "Successfully following: #%{name}"
+      failure: "Failed to follow: #%{name}"
+    destroy:
+      success: "Successfully stopped following: #%{name}"
+      failure: "Failed to stop following: #%{name}"
 
   tokens:
     show:
diff --git a/config/routes.rb b/config/routes.rb
index 7627953bd2c6e59aceb8cee9e2deb9ea90ccfdd1..1dd4938fad5baf4dd462b17690b1266625e843b1 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -4,6 +4,7 @@
 
 Diaspora::Application.routes.draw do
 
+
   # Posting and Reading
 
   resources :aspects do
@@ -34,6 +35,9 @@ Diaspora::Application.routes.draw do
   end
 
   resources :tags, :only => [:index]
+  post    "/tags/:name/tag_followings" => "tag_followings#create", :as => 'tag_tag_followings'
+  delete  "/tags/:name/tag_followings" => "tag_followings#destroy"
+
   get 'tags/:name' => 'tags#show', :as => 'tag'
 
   resources :apps, :only => [:show]
diff --git a/db/migrate/20110701215925_create_tag_followings.rb b/db/migrate/20110701215925_create_tag_followings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c8bb4afbe95b41f9426ad10e4a6aabe2623bb787
--- /dev/null
+++ b/db/migrate/20110701215925_create_tag_followings.rb
@@ -0,0 +1,14 @@
+class CreateTagFollowings < ActiveRecord::Migration
+  def self.up
+    create_table :tag_followings do |t|
+      t.integer :tag_id
+      t.integer :user_id
+
+      t.timestamps
+    end
+  end
+
+  def self.down
+    drop_table :tag_followings
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 085facef9ece0468a2ed1ce00e842f70ab749b92..a702f02810bebe520579b3b81750e3101a528a18 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -326,6 +326,13 @@ ActiveRecord::Schema.define(:version => 20110705003445) do
 
   add_index "services", ["user_id"], :name => "index_services_on_user_id"
 
+  create_table "tag_followings", :force => true do |t|
+    t.integer  "tag_id"
+    t.integer  "user_id"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+  end
+
   create_table "taggings", :force => true do |t|
     t.integer  "tag_id"
     t.integer  "taggable_id"
diff --git a/features/follows_tags.feature b/features/follows_tags.feature
new file mode 100644
index 0000000000000000000000000000000000000000..6271ffed2c7359a10b0efe5ed8f5b741e29abfb7
--- /dev/null
+++ b/features/follows_tags.feature
@@ -0,0 +1,45 @@
+@javascript
+Feature: posting
+  In order to takeover humanity for the good of society
+  As a rock star
+  I want to see what humanity is saying about particular tags
+
+  Background:
+    Given a user with username "bob"
+    And a user with username "alice"
+    When I sign in as "bob@bob.bob"
+
+    And I am on the home page
+
+    And I expand the publisher
+    And I fill in "status_message_fake_text" with "I am da #boss"
+    And I press the first ".public_icon" within "#publisher"
+    And I press "Share"
+    And I wait for the ajax to finish
+    And I wait for the ajax to finish
+
+    And I follow "#boss"
+    And I wait for the ajax to finish
+    Then I should see "I am da #boss"
+
+
+    And I go to the destroy user session page
+
+    And I sign in as "alice@alice.alice"
+    And I search for "#boss"
+    And I press "Follow #boss"
+    And I wait for the ajax to finish
+
+  Scenario: see a tag that I am following
+    When I go to the home page
+    And I follow "#boss"
+    Then I should see "I am da #boss"
+
+  Scenario: can stop following a particular tag
+    When I press "Stop Following #boss"
+
+    And I go to the home page
+    Then I should not see "#boss" within ".left_nav"
+
+
+
diff --git a/features/signs_up.feature b/features/signs_up.feature
index 1796cc531806b1d2148be8b2dc87b10ae5d51887..566b6ebfd04112616de1917007e83eb99722db20 100644
--- a/features/signs_up.feature
+++ b/features/signs_up.feature
@@ -16,7 +16,7 @@ Feature: new user registration
     And I fill in "profile_last_name" with "Hai"
     And I fill in "tags" with "#tags"
     And I press "Save and continue"
-    And I wait for "step 2" to load
+    And I wait for the ajax to finish
     Then I should see "Profile updated"
     And I should see "Would you like to find your Facebook friends on Diaspora?"
     And I follow "Skip"
@@ -31,5 +31,4 @@ Feature: new user registration
   
   Scenario: new user skips the setup wizard
     When I follow "skip getting started"
-    And I wait for "the aspects page" to load
     Then I should be on the aspects page
diff --git a/features/step_definitions/custom_web_steps.rb b/features/step_definitions/custom_web_steps.rb
index c61534ed3d1a7d557e02f70b15e3576b8f3ede7b..cb8548963d97709d024cd7f99da32a1307d19d81 100644
--- a/features/step_definitions/custom_web_steps.rb
+++ b/features/step_definitions/custom_web_steps.rb
@@ -129,15 +129,6 @@ When /^I click ok in the confirm dialog to appear next$/ do
   JS
 end
 
-When /^I wait for "([^\"]*)" to load$/ do |page_name|
-  wait_until(10) do
-    uri = URI.parse(current_url)
-    current_location = uri.path
-    current_location << "?#{uri.query}" unless uri.query.blank?
-    current_location == path_to(page_name)
-  end
-end
-
 Then /^I should get download alert$/ do
   page.evaluate_script("window.alert = function() { return true; }")
 end
@@ -183,7 +174,7 @@ And /^I scroll down$/ do
   wait_until(10) { evaluate_script('$("#infscr-loading:visible").length') == 0 }
 end
 
-When /^I wait for (\d+) seconds$/ do |seconds|
+When /^I wait for (\d+) seconds?$/ do |seconds|
   sleep seconds.to_i
 end
 
diff --git a/public/stylesheets/sass/application.sass b/public/stylesheets/sass/application.sass
index 8077519ca73761c6569e471c1c78fa9b7efb4716..a555a3eafaad67ef5273299e1c55cc245f9f28fc 100644
--- a/public/stylesheets/sass/application.sass
+++ b/public/stylesheets/sass/application.sass
@@ -2786,6 +2786,7 @@ ul#requested-scopes
 
 ul.left_nav
   :margin 0
+    :bottom 20px
   :padding 0
 
   li
@@ -2793,11 +2794,16 @@ ul.left_nav
     :width 100%
 
   a.aspect_selector,
-  a.home_selector
+  a.home_selector,
+  a.tag_selector,
+  .root_element
     :display block
     :width 100%
     :padding 3px 7px
 
+  a.aspect_selector,
+  a.home_selector,
+  a.tag_selector
     &:hover
       @include border-radius(2px)
 
@@ -2841,8 +2847,10 @@ ul.left_nav
     :margin 0
     li
       :width 155px
+
     a.aspect_selector,
-    a.new_aspect
+    a.new_aspect,
+    a.tag_selector
       :padding
         :left 15px
       :width 182px
@@ -2862,7 +2870,8 @@ ul.left_nav
       :width 140px
 
       a.aspect_selector,
-      a.new_aspect
+      a.new_aspect,
+      a.tag_selector
         :width 140px
 
       li:hover
diff --git a/public/stylesheets/sass/ui.sass b/public/stylesheets/sass/ui.sass
index 3f27cb274dfc7212336c8caf2f5b17b31f2cd4de..4a34b1ae459fe05758c760938fb09425b8844472 100644
--- a/public/stylesheets/sass/ui.sass
+++ b/public/stylesheets/sass/ui.sass
@@ -11,6 +11,7 @@
   @include border-radius(2px)
   @include linear-gradient(rgb(248,250,250),rgb(228,223,223))
   @include box-shadow(0,1px,1px,#cfcfcf)
+  @include transition(width, 3s)
 
   :font
     :style normal
@@ -82,6 +83,11 @@
   &:hover
     @include linear-gradient(lighten($creation-blue,3%), darken($creation-blue, 8%))
 
+.button.red_on_hover
+  &:hover
+    @include linear-gradient(desaturate(lighten($red, 20%),20%), desaturate(lighten($red,14%),20%))
+    :color black
+
 .right
   :position absolute
   :right 0
diff --git a/spec/controllers/aspects_controller_spec.rb b/spec/controllers/aspects_controller_spec.rb
index 029c7ff081965be37ad80f6c4a4b3f809a57b0c1..8308737383cbacd090ad9a89c4a8cfc197632b9a 100644
--- a/spec/controllers/aspects_controller_spec.rb
+++ b/spec/controllers/aspects_controller_spec.rb
@@ -331,4 +331,23 @@ describe AspectsController do
       @alices_aspect_1.reload.contacts_visible.should be_false
     end
   end
+
+  context 'helper methods' do
+    before do
+      @tag = ActsAsTaggableOn::Tag.create!(:name => "partytimeexcellent")
+      TagFollowing.create!(:tag => @tag, :user => alice )
+      alice.should_receive(:followed_tags).once.and_return([42])
+    end
+
+    describe 'tags' do
+      it 'queries current_users tag if there are tag_followings' do
+        @controller.tags.should == [42]
+      end
+
+      it 'does not query twice' do
+        @controller.tags.should == [42]
+        @controller.tags.should == [42]
+      end
+    end
+  end
 end
diff --git a/spec/controllers/tag_followings_controller_spec.rb b/spec/controllers/tag_followings_controller_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..60dfb6bdc4aeae471ed9e59bffa7c8754929d448
--- /dev/null
+++ b/spec/controllers/tag_followings_controller_spec.rb
@@ -0,0 +1,89 @@
+#   Copyright (c) 2010, Diaspora Inc.  This file is
+#   licensed under the Affero General Public License version 3 or later.  See
+#   the COPYRIGHT file.
+
+require 'spec_helper'
+
+describe TagFollowingsController do
+
+  def valid_attributes
+    {:name => "partytimeexcellent"}
+  end
+
+  before do
+    @tag = ActsAsTaggableOn::Tag.create!(:name => "partytimeexcellent")
+    sign_in :user, bob
+  end
+
+  describe "POST create" do
+    describe "with valid params" do
+      it "creates a new TagFollowing" do
+        expect {
+          post :create, valid_attributes
+        }.to change(TagFollowing, :count).by(1)
+      end
+
+      it "assigns a newly created tag_following as @tag_following" do
+        post :create, valid_attributes
+        assigns(:tag_following).should be_a(TagFollowing)
+        assigns(:tag_following).should be_persisted
+      end
+
+      it 'creates the tag if it does not already exist' do
+        expect {
+          post :create, :name => "tomcruisecontrol"
+        }.to change(ActsAsTaggableOn::Tag, :count).by(1)
+      end
+
+      it 'does not create the tag following for non signed in user' do
+        expect {
+          post :create, valid_attributes.merge(:user_id => alice.id)
+        }.to_not change(alice.tag_followings, :count).by(1)
+      end
+
+      it "redirects and flashes success to the tag page" do
+        post :create, valid_attributes
+
+        response.should redirect_to(tag_path(:name => valid_attributes[:name]))
+        flash[:notice].should == "Successfully following: ##{valid_attributes[:name]}"
+      end
+
+      it "redirects and flashes error if you already have a tag" do
+        TagFollowing.any_instance.stub(:save).and_return(false)
+        post :create, valid_attributes
+
+        response.should redirect_to(tag_path(:name => valid_attributes[:name]))
+        flash[:error].should == "Failed to follow: ##{valid_attributes[:name]}"
+      end
+    end
+  end
+
+  describe "DELETE destroy" do
+    before do
+      TagFollowing.create!(:tag => @tag, :user => bob )
+      TagFollowing.create!(:tag => @tag, :user => alice )
+    end
+
+    it "destroys the requested tag_following" do
+      expect {
+        delete :destroy, valid_attributes
+      }.to change(TagFollowing, :count).by(-1)
+    end
+
+    it "redirects and flashes error if you already don't follow the tag" do
+      delete :destroy, valid_attributes
+
+      response.should redirect_to(tag_path(:name => valid_attributes[:name]))
+      flash[:notice].should == "Successfully stopped following: ##{valid_attributes[:name]}"
+    end
+
+    it "redirects and flashes error if you already don't follow the tag" do
+      TagFollowing.any_instance.stub(:destroy).and_return(false)
+      delete :destroy, valid_attributes
+
+      response.should redirect_to(tag_path(:name => valid_attributes[:name]))
+      flash[:error].should == "Failed to stop following: ##{valid_attributes[:name]}"
+    end
+  end
+
+end
diff --git a/spec/controllers/tags_controller_spec.rb b/spec/controllers/tags_controller_spec.rb
index 492d66897c218be437eaa8edb6da15cb57ca0961..34d892e5f2afade260a5debabd218333193e1d1a 100644
--- a/spec/controllers/tags_controller_spec.rb
+++ b/spec/controllers/tags_controller_spec.rb
@@ -62,6 +62,13 @@ describe TagsController do
         assigns(:posts).models.should == [other_post]
         response.status.should == 200
       end
+
+      it 'displays a public post that was sent to no one' do
+        stranger = Factory(:user_with_aspect)
+        stranger_post = stranger.post(:status_message, :text => "#hello", :public => true, :to => 'all')
+        get :show, :name => 'hello'
+        assigns(:posts).models.should == [stranger_post]
+      end
     end
 
     context "not signed in" do
@@ -106,4 +113,24 @@ describe TagsController do
       end
     end
   end
-end
\ No newline at end of file
+
+  context 'helper methods' do
+    describe 'tag_followed?' do
+      before do
+        sign_in bob
+        @tag = ActsAsTaggableOn::Tag.create!(:name => "partytimeexcellent")
+        @controller.stub(:current_user).and_return(bob)
+        @controller.stub(:params).and_return({:name => "partytimeexcellent"})
+      end
+
+      it 'returns true if the following already exists' do
+        TagFollowing.create!(:tag => @tag, :user => bob )
+        @controller.tag_followed?.should be_true
+      end
+
+      it 'returns false if the following does not already exist' do
+        @controller.tag_followed?.should be_false
+      end
+    end
+  end
+end
diff --git a/spec/models/tag_following_spec.rb b/spec/models/tag_following_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3b1614dfab9c185739d8f55e25a938a4a969186a
--- /dev/null
+++ b/spec/models/tag_following_spec.rb
@@ -0,0 +1,16 @@
+require 'spec_helper'
+
+describe TagFollowing do
+  before do
+    @tag = ActsAsTaggableOn::Tag.create(:name => "partytimeexcellent")
+    TagFollowing.create!(:tag => @tag, :user => alice)
+  end
+
+  it 'validates uniqueness of tag_following scoped through user' do
+    TagFollowing.new(:tag => @tag, :user => alice).valid?.should be_false
+  end
+
+  it 'allows multiple tag followings for different users' do
+    TagFollowing.new(:tag => @tag, :user => bob).valid?.should be_true
+  end
+end