Merge branch 'follow-users' into 'master'
Follow users See merge request !1
This commit is contained in:
commit
be8a9fdc10
2
Rakefile
2
Rakefile
|
@ -15,6 +15,8 @@ namespace :justask do
|
|||
answered = Answer.where(user: user).count
|
||||
asked = Question.where(user: user).where(author_is_anonymous: false).count
|
||||
commented = Comment.where(user: user).count
|
||||
user.friend_count = user.friends.count
|
||||
user.follower_count = user.followers.count
|
||||
user.answered_count = answered
|
||||
user.asked_count = asked
|
||||
user.commented_count = commented
|
||||
|
|
|
@ -72,7 +72,6 @@ $(document).on "click", "button[name=ib-answer]", ->
|
|||
btn.button "reset"
|
||||
$("textarea[name=ib-answer][data-id=#{iid}]").removeAttr "readonly"
|
||||
|
||||
# TODO
|
||||
$(document).on "click", "button[name=ab-destroy]", ->
|
||||
btn = $(this)
|
||||
btn.button "loading"
|
||||
|
@ -92,6 +91,49 @@ $(document).on "click", "button[name=ab-destroy]", ->
|
|||
complete: (jqxhr, status) ->
|
||||
btn.button "reset"
|
||||
|
||||
$(document).on "click", "button[name=user-action]", ->
|
||||
btn = $(this)
|
||||
btn.button "loading"
|
||||
target = btn[0].dataset.target
|
||||
action = btn[0].dataset.action
|
||||
count = Number($("h4.entry-text#follower-count").html())
|
||||
|
||||
target_url = switch action
|
||||
when 'follow'
|
||||
count++
|
||||
'/ajax/create_friend'
|
||||
when 'unfollow'
|
||||
count--
|
||||
'/ajax/destroy_friend'
|
||||
|
||||
success = false
|
||||
|
||||
$.ajax
|
||||
url: target_url
|
||||
type: 'POST'
|
||||
data:
|
||||
screen_name: target
|
||||
success: (data, status, jqxhr) ->
|
||||
success = data.success
|
||||
if data.success
|
||||
$("h4.entry-text#follower-count").html(count)
|
||||
showNotification data.message, data.success
|
||||
error: (jqxhr, status, error) ->
|
||||
console.log jqxhr, status, error
|
||||
showNotification "An error occurred, a developer should check the console for details", false
|
||||
complete: (jqxhr, status) ->
|
||||
btn.button "reset"
|
||||
if success
|
||||
switch action
|
||||
when 'follow'
|
||||
btn[0].dataset.action = 'unfollow'
|
||||
btn.attr 'class', 'btn btn-default btn-block'
|
||||
btn.html 'Unfollow'
|
||||
when 'unfollow'
|
||||
btn[0].dataset.action = 'follow'
|
||||
btn.attr 'class', 'btn btn-primary btn-block'
|
||||
btn.html 'Follow'
|
||||
|
||||
$(document).on "click", "button#create-account", ->
|
||||
Turbolinks.visit "/sign_up"
|
||||
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
class Ajax::FriendController < ApplicationController
|
||||
def create
|
||||
params.require :screen_name
|
||||
|
||||
target_user = User.find_by_screen_name(params[:screen_name])
|
||||
|
||||
begin
|
||||
current_user.follow target_user
|
||||
rescue
|
||||
@status = :fail
|
||||
@message = "You are already following that user."
|
||||
@success = false
|
||||
return
|
||||
end
|
||||
|
||||
@status = :okay
|
||||
@message = "Successfully followed user."
|
||||
@success = true
|
||||
end
|
||||
|
||||
def destroy
|
||||
params.require :screen_name
|
||||
|
||||
target_user = User.find_by_screen_name(params[:screen_name])
|
||||
|
||||
begin
|
||||
current_user.unfollow target_user
|
||||
rescue
|
||||
@status = :fail
|
||||
@message = "You are not following that user."
|
||||
@success = false
|
||||
return
|
||||
end
|
||||
|
||||
@status = :okay
|
||||
@message = "Successfully unfollowed user."
|
||||
@success = true
|
||||
end
|
||||
end
|
|
@ -0,0 +1,6 @@
|
|||
class Relationship < ActiveRecord::Base
|
||||
belongs_to :source, class_name: 'User'
|
||||
belongs_to :target, class_name: 'User'
|
||||
validates :source_id, presence: true
|
||||
validates :target_id, presence: true
|
||||
end
|
|
@ -11,7 +11,15 @@ class User < ActiveRecord::Base
|
|||
has_many :answers, dependent: :destroy
|
||||
has_many :comments, dependent: :destroy
|
||||
has_many :inboxes, dependent: :destroy
|
||||
|
||||
has_many :active_relationships, class_name: 'Relationship',
|
||||
foreign_key: 'source_id',
|
||||
dependent: :destroy
|
||||
has_many :passive_relationships, class_name: 'Relationship',
|
||||
foreign_key: 'target_id',
|
||||
dependent: :destroy
|
||||
has_many :friends, through: :active_relationships, source: :target
|
||||
has_many :followers, through: :passive_relationships, source: :source
|
||||
|
||||
SCREEN_NAME_REGEX = /\A[a-zA-Z0-9_]{1,16}\z/
|
||||
|
||||
validates :screen_name, presence: true, format: { with: SCREEN_NAME_REGEX }, uniqueness: { case_sensitive: false }
|
||||
|
@ -34,4 +42,32 @@ class User < ActiveRecord::Base
|
|||
where(conditions).first
|
||||
end
|
||||
end
|
||||
|
||||
# @return [Array] the users' timeline
|
||||
def timeline
|
||||
Answer.where("user_id in (?) OR user_id = ?", friend_ids, id).order(:created_at).reverse_order
|
||||
end
|
||||
|
||||
# follows an user.
|
||||
def follow(target_user)
|
||||
active_relationships.create(target: target_user)
|
||||
|
||||
# increment counts
|
||||
increment! :friend_count
|
||||
target_user.increment! :follower_count
|
||||
end
|
||||
|
||||
# unfollows an user
|
||||
def unfollow(target_user)
|
||||
active_relationships.find_by(target: target_user).destroy
|
||||
|
||||
# decrement counts
|
||||
decrement! :friend_count
|
||||
target_user.decrement! :follower_count
|
||||
end
|
||||
|
||||
# @return [Boolean] true if +current_user+ is following +target_user+
|
||||
def following?(target_user)
|
||||
friends.include? target_user
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
- if user_signed_in?
|
||||
.container
|
||||
%h1 Static#index
|
||||
%h1 Timeline
|
||||
= render 'layouts/messages'
|
||||
|
||||
%p Find me in app/views/static/index.html.haml
|
||||
- current_user.timeline.each do |answer|
|
||||
= render 'shared/answerbox', a: answer
|
||||
= render "shared/links"
|
||||
- else
|
||||
.jumbotron
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
- if user_signed_in?
|
||||
- if @user == current_user
|
||||
%a.btn.btn-default.btn-block{href: edit_user_profile_path} Edit profile
|
||||
- else
|
||||
- if current_user.following? @user
|
||||
%button#editprofile.btn.btn-default.btn-block{type: :button, name: 'user-action', 'data-action' => :unfollow, 'data-target' => @user.screen_name}
|
||||
Unfollow
|
||||
- else
|
||||
%button#editprofile.btn.btn-primary.btn-block{type: :button, name: 'user-action', 'data-action' => :follow, 'data-target' => @user.screen_name}
|
||||
Follow
|
|
@ -14,14 +14,15 @@
|
|||
%p.user-admin
|
||||
%i.fa.fa-flask
|
||||
Admin
|
||||
%h4.entry-text= @user.follower_count
|
||||
%h6.entry-subtext Followers
|
||||
%h4.entry-text= @user.friend_count
|
||||
%h6.entry-subtext Followings
|
||||
%h4.entry-text= @user.asked_count
|
||||
%h4.entry-text#follower-count= @user.follower_count
|
||||
%h6.entry-subtext Follower
|
||||
%h4.entry-text#friend-count= @user.friend_count
|
||||
%h6.entry-subtext Following
|
||||
%h4.entry-text#asked-count= @user.asked_count
|
||||
%h6.entry-subtext Questions
|
||||
%h4.entry-text= @user.answered_count
|
||||
%h4.entry-text#answered-count= @user.answered_count
|
||||
%h6.entry-subtext Answers
|
||||
= render 'user/actions'
|
||||
.hidden-xs= render 'shared/links'
|
||||
.col-md-9.col-xs-12.col-sm-9
|
||||
= render 'shared/questionbox'
|
||||
|
|
|
@ -27,6 +27,8 @@ Rails.application.routes.draw do
|
|||
match '/ask', to: 'question#create', via: :post, as: :ask
|
||||
match '/answer', to: 'inbox#destroy', via: :post, as: :answer
|
||||
match '/destroy_answer', to: 'answer#destroy', via: :post, as: :destroy_answer
|
||||
match '/create_friend', to: 'friend#create', via: :post, as: :create_friend
|
||||
match '/destroy_friend', to: 'friend#destroy', via: :post, as: :destroy_friend
|
||||
end
|
||||
|
||||
match '/inbox', to: 'inbox#show', via: 'get'
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
class CreateRelationships < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :relationships do |t|
|
||||
t.integer :source_id
|
||||
t.integer :target_id
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
add_index :relationships, :source_id
|
||||
add_index :relationships, :target_id
|
||||
add_index :relationships, [:source_id, :target_id], unique: true
|
||||
end
|
||||
end
|
13
db/schema.rb
13
db/schema.rb
|
@ -11,7 +11,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20141129211448) do
|
||||
ActiveRecord::Schema.define(version: 20141130130221) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
@ -59,6 +59,17 @@ ActiveRecord::Schema.define(version: 20141129211448) do
|
|||
|
||||
add_index "questions", ["user_id", "created_at"], name: "index_questions_on_user_id_and_created_at", using: :btree
|
||||
|
||||
create_table "relationships", force: true do |t|
|
||||
t.integer "source_id"
|
||||
t.integer "target_id"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
|
||||
add_index "relationships", ["source_id", "target_id"], name: "index_relationships_on_source_id_and_target_id", unique: true, using: :btree
|
||||
add_index "relationships", ["source_id"], name: "index_relationships_on_source_id", using: :btree
|
||||
add_index "relationships", ["target_id"], name: "index_relationships_on_target_id", using: :btree
|
||||
|
||||
create_table "users", force: true do |t|
|
||||
t.string "email", default: "", null: false
|
||||
t.string "encrypted_password", default: "", null: false
|
||||
|
|
Loading…
Reference in New Issue