WIP you can now follow a tag, needs a clean up, and ajax love
This commit is contained in:
parent
77d28b4117
commit
1e4ee472b7
18 changed files with 314 additions and 33 deletions
|
|
@ -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,27 @@ 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
|
||||
if tag_followings != [] && @tags != []
|
||||
@tags ||= ActsAsTaggableOn::Tag.where(:id => tag_followings.map(&:id)).all
|
||||
else
|
||||
@tags ||= []
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def save_sort_order
|
||||
if params[:sort_order].present?
|
||||
|
|
|
|||
31
app/controllers/tag_followings_controller.rb
Normal file
31
app/controllers/tag_followings_controller.rb
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
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)
|
||||
|
||||
respond_to do |format|
|
||||
if @tag_following.save
|
||||
format.html { redirect_to(tag_path(:name => params[:name]), :notice => "Successfully following: #{params[:name]}" ) }
|
||||
format.xml { render :xml => @tag_following, :status => :created, :location => @tag_following }
|
||||
else
|
||||
render :nothing => true, :status => :unprocessable_entity
|
||||
end
|
||||
end
|
||||
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
|
||||
render :nothing => true, :status => 200
|
||||
else
|
||||
render :nothing => true, :status => 410
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -69,4 +69,8 @@ class TagsController < ApplicationController
|
|||
@people_count = Person.where(:id => profiles.map{|p| p.person_id}).count
|
||||
end
|
||||
end
|
||||
|
||||
# def tag_following?
|
||||
# TagFollowings.join(:tags)
|
||||
# end
|
||||
end
|
||||
|
|
|
|||
2
app/helpers/tag_followings_helper.rb
Normal file
2
app/helpers/tag_followings_helper.rb
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
module TagFollowingsHelper
|
||||
end
|
||||
6
app/models/tag_following.rb
Normal file
6
app/models/tag_following.rb
Normal file
|
|
@ -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
|
||||
|
|
@ -39,6 +39,7 @@ 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 :authorizations, :class_name => 'OAuth2::Provider::Models::ActiveRecord::Authorization', :foreign_key => :resource_owner_id
|
||||
has_many :applications, :through => :authorizations, :source => :client
|
||||
|
|
|
|||
|
|
@ -4,19 +4,9 @@
|
|||
|
||||
ContactEdit.updateNumber("<%= @contact.person_id%>");
|
||||
|
||||
var element = $(".add[data-aspect_id=<%= @aspect.id %>][data-person_id=<%= @contact.person_id%>]");
|
||||
var element = $(".stream_container");
|
||||
|
||||
if( $("#no_contacts").is(':visible') ) {
|
||||
$("#no_contacts").fadeOut(200);
|
||||
}
|
||||
|
||||
$(".badges").prepend("<%= escape_javascript( aspect_badge(@aspect).html_safe ) %>");
|
||||
element.parent().html("<%= escape_javascript(render('aspect_memberships/add_to_aspect', :aspect_id => @aspect.id, :person_id => @person.id)) %>");
|
||||
|
||||
if($('#aspects_list').length == 1) {
|
||||
$('.aspect_list').attr('data-contact_id', "<%= @contact_id %>");
|
||||
$('.aspect_list ul').find('.add').each(function(a,b){$(b).attr('href', $(b).attr('href').replace('contacts','aspect_memberships'));})
|
||||
};
|
||||
element.html("<%= escape_javascript(render('aspect_memberships/add_to_aspect', :aspect_id => @aspect.id, :person_id => @person.id)) %>");
|
||||
|
||||
element.fadeTo(200,1);
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,15 @@
|
|||
.section
|
||||
= render 'aspects/aspect_listings'
|
||||
|
||||
%ul.left_nav
|
||||
%li
|
||||
= t('aspects.index.tags_following')
|
||||
|
||||
%ul.sub_nav
|
||||
- for tg in tags
|
||||
%li
|
||||
= link_to "##{tg.name}", tag_path(:name => tg.name)
|
||||
|
||||
.span-13.append-1.prepend-5
|
||||
#aspect_stream_container.stream_container
|
||||
= render 'aspect_stream',
|
||||
|
|
|
|||
|
|
@ -30,17 +30,20 @@
|
|||
#author_info
|
||||
- if user_signed_in? && current_user.person != @person
|
||||
.right
|
||||
= button_to "Follow ##{params[:name]}", :class => "button"
|
||||
- unless true #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('.stop_following', :tag => params[:name]), tag_tag_followings_path(:name => params[:name]), :method => :post, :class => 'button 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]}")
|
||||
#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]}")
|
||||
|
||||
|
|
|
|||
|
|
@ -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,8 @@ 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}"
|
||||
stop_following: "Stop Following #%{tag}"
|
||||
|
||||
tokens:
|
||||
show:
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
14
db/migrate/20110701215925_create_tag_followings.rb
Normal file
14
db/migrate/20110701215925_create_tag_followings.rb
Normal file
|
|
@ -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
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -10,22 +10,37 @@ Feature: posting
|
|||
When I sign in as "bob@bob.bob"
|
||||
And I am on the home page
|
||||
|
||||
|
||||
Scenario: see a tag that I am following
|
||||
Given I expand the publisher
|
||||
And I fill in "status_message_fake_text" with "I am ALICE"
|
||||
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
|
||||
|
||||
When I go to the home page
|
||||
Then I should see "I am da #boss"
|
||||
And I wait for 5 seconds
|
||||
|
||||
And I follow "#boss"
|
||||
And I wait for the ajax to finish
|
||||
And I debug
|
||||
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 "#alice"
|
||||
And I press "Follow #alice"
|
||||
And I go to the home page
|
||||
And I press "#alice"
|
||||
Then I should see "I am #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: see that I'm following a particular tag
|
||||
Then I should see "Following #boss"
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -331,4 +331,66 @@ 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 => bob )
|
||||
end
|
||||
|
||||
describe 'tag_followings' do
|
||||
it 'does nothing if no-one is signed in' do
|
||||
@controller.stub!(:current_user).and_return(nil)
|
||||
@controller.tag_followings.should be_nil
|
||||
end
|
||||
|
||||
it 'queries current_users tag_followings' do
|
||||
alice.should_receive(:tag_followings).once.and_return([42])
|
||||
|
||||
@controller.stub(:current_user).and_return(alice)
|
||||
@controller.tag_followings.should == [42]
|
||||
end
|
||||
|
||||
it 'does not query twice' do
|
||||
alice.should_receive(:tag_followings).once.and_return([42])
|
||||
@controller.stub(:current_user).and_return(alice)
|
||||
|
||||
@controller.tag_followings.should == [42]
|
||||
@controller.tag_followings.should == [42]
|
||||
end
|
||||
end
|
||||
|
||||
describe 'tags' do
|
||||
it 'does nothing there are no tag_followings' do
|
||||
@controller.stub!(:tag_followings).and_return([])
|
||||
@controller.tags.should == []
|
||||
end
|
||||
|
||||
context "querying" do
|
||||
before do
|
||||
@ids = [1,2,3]
|
||||
@tag_followings = @ids.map do |n|
|
||||
tf = mock()
|
||||
tf.should_receive(:id).and_return(n)
|
||||
tf
|
||||
end
|
||||
|
||||
query = mock
|
||||
query.should_receive(:all).and_return([42])
|
||||
|
||||
ActsAsTaggableOn::Tag.should_receive(:where).with(:id => @ids).once.and_return(query)
|
||||
@controller.stub(:tag_followings).and_return(@tag_followings)
|
||||
end
|
||||
|
||||
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
|
||||
end
|
||||
|
|
|
|||
76
spec/controllers/tag_followings_controller_spec.rb
Normal file
76
spec/controllers/tag_followings_controller_spec.rb
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
# 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 to the tag page" do
|
||||
post :create, valid_attributes
|
||||
response.should redirect_to(tag_path(:name => valid_attributes[:name]))
|
||||
end
|
||||
|
||||
it "returns a 406 if you already have a tag" do
|
||||
TagFollowing.any_instance.stub(:save).and_return(false)
|
||||
post :create, valid_attributes
|
||||
response.code.should == "406"
|
||||
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 "returns a 410 if you already have a tag" do
|
||||
TagFollowing.any_instance.stub(:destroy).and_return(false)
|
||||
delete :destroy, valid_attributes
|
||||
response.code.should == "410"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -106,4 +106,23 @@ describe TagsController do
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'helper methods' do
|
||||
describe 'tag_followed?' do
|
||||
before do
|
||||
sign_in alice
|
||||
@tag = ActsAsTaggableOn::Tag.create!(:name => "partytimeexcellent")
|
||||
@controller.stub(:current_user).and_return(bob)
|
||||
end
|
||||
|
||||
it 'returns true if the following already exists' do
|
||||
TagFollowing.create!(:tag => @tag, :user => bob )
|
||||
@controller.tag_following?.should be_true
|
||||
end
|
||||
|
||||
it 'returns false if the following does not already exist' do
|
||||
@controller.tag_following?.should be_false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
16
spec/models/tag_following_spec.rb
Normal file
16
spec/models/tag_following_spec.rb
Normal file
|
|
@ -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
|
||||
Loading…
Reference in a new issue