Skip to content

Commit

Permalink
用 actions 表来代替 Like, Folllow, Block 等功能之前的 Array 字段存储. (#857)
Browse files Browse the repository at this point in the history
  • Loading branch information
huacnlee authored Feb 11, 2017
1 parent 858f7ee commit 1833182
Show file tree
Hide file tree
Showing 35 changed files with 321 additions and 294 deletions.
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ gem 'devise-encryptable'
gem 'notifications'
gem 'ruby-push-notifications'

# 赞、关注、收藏、屏蔽等功能的数据结构
gem 'action-store'

# 分页
gem 'will_paginate'

Expand Down
5 changes: 4 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
GEM
remote: https://gems.ruby-china.org/
specs:
action-store (0.2.0)
rails (>= 4.2.0, < 5.1)
actioncable (5.0.1)
actionpack (= 5.0.1)
nio4r (~> 1.2)
Expand Down Expand Up @@ -402,7 +404,7 @@ GEM
url (0.3.2)
warden (1.2.6)
rack (>= 1.0)
websocket-driver (0.6.4)
websocket-driver (0.6.5)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.2)
will_paginate (3.1.5)
Expand All @@ -414,6 +416,7 @@ PLATFORMS
ruby

DEPENDENCIES
action-store
auto-space
better_errors
binding_of_caller
Expand Down
2 changes: 2 additions & 0 deletions app/controllers/api/v3/likes_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class LikesController < Api::V3::ApplicationController
# - count [Integer] 已赞的数量
def create
current_user.like(likeable)
likeable.reload
data = { obj_type: params[:obj_type], obj_id: likeable.id, count: likeable.likes_count }
render json: data
end
Expand All @@ -31,6 +32,7 @@ def create
# @return (see #create)
def destroy
current_user.unlike(likeable)
likeable.reload
data = { obj_type: params[:obj_type], obj_id: likeable.id, count: likeable.likes_count }
render json: data
end
Expand Down
26 changes: 8 additions & 18 deletions app/controllers/api/v3/topics_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ def index
if params[:node_id].blank?
@topics = Topic
if current_user
@topics = @topics.without_nodes(current_user.blocked_node_ids)
@topics = @topics.without_users(current_user.blocked_user_ids)
@topics = @topics.without_nodes(current_user.block_node_ids)
@topics = @topics.without_users(current_user.block_user_ids)
else
@topics = @topics.without_hide_nodes
end
Expand Down Expand Up @@ -62,9 +62,9 @@ def show
if current_user
# 处理通知
current_user.read_topic(@topic)
@meta[:followed] = @topic.followed?(current_user.id)
@meta[:liked] = current_user.liked?(@topic)
@meta[:favorited] = current_user.favorited_topic?(@topic.id)
@meta[:followed] = current_user.follow_topic?(@topic)
@meta[:liked] = current_user.like_topic?(@topic)
@meta[:favorited] = current_user.favorite_topic?(@topic)
end
end

Expand Down Expand Up @@ -147,17 +147,7 @@ def replies

@replies = Reply.unscoped.where(topic_id: @topic.id).order(:id).includes(:user)
@replies = @replies.offset(params[:offset].to_i).limit(params[:limit].to_i)

@user_liked_reply_ids = []
if current_user
# 找出用户 like 过的 Reply,给 JS 处理 like 功能的状态
@replies.each do |r|
unless r.liked_user_ids.index(current_user.id).nil?
@user_liked_reply_ids << r.id
end
end
end

@user_liked_reply_ids = current_user&.like_reply_ids || []
@meta = { user_liked_reply_ids: @user_liked_reply_ids }
end

Expand All @@ -184,15 +174,15 @@ def create_replies
#
# POST /api/v3/topics/:id/follow
def follow
@topic.push_follower(current_user.id)
current_user.follow_topic(@topic)
render json: { ok: 1 }
end

# 取消关注话题
#
# POST /api/v3/topics/:id/unfollow
def unfollow
@topic.pull_follower(current_user.id)
current_user.unfollow_topic(@topic)
render json: { ok: 1 }
end

Expand Down
17 changes: 7 additions & 10 deletions app/controllers/api/v3/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ def show
@meta = { followed: false, blocked: false }

if current_user
@meta[:followed] = current_user.followed?(@user)
@meta[:blocked] = current_user.blocked_user?(@user)
@meta[:followed] = current_user.follow_user?(@user)
@meta[:blocked] = current_user.block_user?(@user)
end
end

Expand Down Expand Up @@ -95,9 +95,7 @@ def favorites
optional! :offset, type: Integer, default: 0
optional! :limit, type: Integer, default: 20, values: 1..150

@topic_ids = @user.favorite_topic_ids.reverse[params[:offset].to_i, params[:limit].to_i]
@topics = Topic.where(id: @topic_ids).fields_for_list.includes(:user)
@topics = @topics.to_a.sort_by { |topic| @topic_ids.index(topic.id) }
@topics = @user.favorite_topics.includes(:user).order("actions.id desc").offset(params[:offset]).limit(params[:limit])
render 'topics'
end

Expand All @@ -112,7 +110,7 @@ def followers
optional! :offset, type: Integer, default: 0
optional! :limit, type: Integer, default: 20, values: 1..150

@users = @user.followers.fields_for_list.offset(params[:offset]).limit(params[:limit])
@users = @user.follow_by_users.fields_for_list.order("actions.id asc").offset(params[:offset]).limit(params[:limit])
end

# 获取某个用户的关注者列表
Expand All @@ -125,7 +123,7 @@ def following
optional! :offset, type: Integer, default: 0
optional! :limit, type: Integer, default: 20, values: 1..150

@users = @user.following.fields_for_list.offset(params[:offset]).limit(params[:limit])
@users = @user.follow_users.fields_for_list.order("actions.id asc").offset(params[:offset]).limit(params[:limit])
end

# 获取用户的已屏蔽的人(只能获取自己的)
Expand All @@ -138,10 +136,9 @@ def blocked
optional! :offset, type: Integer, default: 0
optional! :limit, type: Integer, default: 20, values: 1..150

raise AccessDenied.new('不可以获取其他人的 blocked_users 列表。') if current_user.id != @user.id
raise AccessDenied.new('不可以获取其他人的 block_users 列表。') if current_user.id != @user.id

user_ids = current_user.blocked_user_ids[params[:offset].to_i, params[:limit].to_i]
@users = User.where(id: user_ids)
@users = current_user.block_users.fields_for_list.order("actions.id asc").offset(params[:offset]).limit(params[:limit])
end

# 关注用户
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/likes_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ class LikesController < ApplicationController
before_action :set_likeable

def index
@users = @item.liked_users
@users = @item.like_by_users.order('actions.id asc')
render :index, layout: false
end

Expand Down
25 changes: 6 additions & 19 deletions app/controllers/topics_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ def index
@topics = Topic.last_actived.without_suggest
@topics =
if current_user
@topics.without_nodes(current_user.blocked_node_ids)
.without_users(current_user.blocked_user_ids)
@topics.without_nodes(current_user.block_node_ids)
.without_users(current_user.block_user_ids)
else
@topics.without_hide_nodes
end
Expand Down Expand Up @@ -95,7 +95,6 @@ def show

@replies = Reply.unscoped.where(topic_id: @topic.id).order(:id).all

check_current_user_liked_replies
check_current_user_status_for_topic
set_special_node_active_menu
fresh_when([@topic, @node, @show_raw, @replies, @has_followed, @has_favorited, @can_reply])
Expand Down Expand Up @@ -164,12 +163,12 @@ def unfavorite
end

def follow
@topic.push_follower(current_user.id)
current_user.follow_topic(@topic)
render plain: '1'
end

def unfollow
@topic.pull_follower(current_user.id)
current_user.unfollow_topic(@topic)
render plain: '1'
end

Expand Down Expand Up @@ -212,26 +211,14 @@ def ability_team_id
team.id
end

def check_current_user_liked_replies
return false unless current_user

# 找出用户 like 过的 Reply,给 JS 处理 like 功能的状态
@user_liked_reply_ids = []
@replies.each do |r|
unless r.liked_user_ids.index(current_user.id).nil?
@user_liked_reply_ids << r.id
end
end
end

def check_current_user_status_for_topic
return false unless current_user
# 通知处理
current_user.read_topic(@topic, replies_ids: @replies.collect(&:id))
# 是否关注过
@has_followed = @topic.followed?(current_user.id)
@has_followed = current_user.follow_topic?(@topic)
# 是否收藏
@has_favorited = current_user.favorited_topic?(@topic.id)
@has_favorited = current_user.favorite_topic?(@topic)
end

def set_special_node_active_menu
Expand Down
10 changes: 4 additions & 6 deletions app/controllers/users/user_actions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ def replies
end

def favorites
@topic_ids = @user.favorite_topic_ids.reverse.paginate(page: params[:page], per_page: 40)
@topics = Topic.where(id: @topic_ids).fields_for_list
@topics = @topics.to_a.sort_by { |topic| @topic_ids.index(topic.id) }
@topics = @user.favorite_topics.includes(:user).order("actions.id desc").paginate(page: params[:page], per_page: 40)
fresh_when([@topics])
end

Expand Down Expand Up @@ -57,7 +55,7 @@ def blocked
render_404
end

@blocked_users = User.where(id: current_user.blocked_user_ids).paginate(page: params[:page], per_page: 20)
@block_users = @user.block_users.order("actions.id asc").paginate(page: params[:page], per_page: 20)
end

def follow
Expand All @@ -71,12 +69,12 @@ def unfollow
end

def followers
@users = @user.followers.fields_for_list.paginate(page: params[:page], per_page: 60)
@users = @user.follow_by_users.order("actions.id asc").paginate(page: params[:page], per_page: 60)
fresh_when([@users])
end

def following
@users = @user.following.fields_for_list.paginate(page: params[:page], per_page: 60)
@users = @user.follow_users.order("actions.id asc").paginate(page: params[:page], per_page: 60)
render template: '/users/followers' if stale?(etag: [@users], template: 'users/followers')
end

Expand Down
12 changes: 11 additions & 1 deletion app/helpers/likes_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,18 @@ def likeable_tag(likeable, opts = {})
label = "#{likeable.likes_count} 个赞"
label = '' if likeable.likes_count == 0

liked = false

if opts[:cache].blank? && current_user
if likeable.is_a?(Topic)
liked = current_user.like_topic_ids.include?(likeable.id)
elsif likeable.is_a?(Reply)
liked = current_user.like_reply_ids.include?(likeable.id)
end
end

title, state, icon_name =
if opts[:cache].blank? && likeable.liked_by_user?(current_user)
if opts[:cache].blank? && liked
['取消赞', 'active', 'heart']
else
['赞', '', 'heart']
Expand Down
4 changes: 2 additions & 2 deletions app/helpers/topics_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ def topic_favorite_tag(topic, opts = {})
opts[:class] ||= ''
class_name = ''
link_title = '收藏'
if current_user && current_user.favorite_topic_ids.include?(topic.id)
if current_user && current_user.favorite_topic?(topic)
class_name = 'active'
link_title = '取消收藏'
end
Expand All @@ -24,7 +24,7 @@ def topic_follow_tag(topic, opts = {})
return '' if owner?(topic)
opts[:class] ||= ''
class_name = 'follow'
class_name += ' active' if topic.follower_ids.include?(current_user.id)
class_name += ' active' if current_user.follow_topic?(topic)
if opts[:class].present?
class_name += ' ' + opts[:class]
end
Expand Down
6 changes: 3 additions & 3 deletions app/helpers/users_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def render_user_level_tag(user)
def block_node_tag(node)
return '' if current_user.blank?
return '' if node.blank?
blocked = current_user.blocked_node_ids.include?(node.id)
blocked = current_user.block_node?(node)
class_names = 'btn btn-default btn-sm button-block-node'
icon = '<i class="fa fa-eye-slash"></i>'
if blocked
Expand All @@ -94,7 +94,7 @@ def block_user_tag(user)
return '' if current_user.blank?
return '' if user.blank?
return '' if current_user.id == user.id
blocked = current_user.blocked_user_ids.include?(user.id)
blocked = current_user.block_user?(user)
class_names = 'button-block-user btn btn-default btn-block'
icon = '<i class="fa fa-eye-slash"></i>'
if blocked
Expand All @@ -108,7 +108,7 @@ def follow_user_tag(user, opts = {})
return '' if current_user.blank?
return '' if user.blank?
return '' if current_user.id == user.id
followed = current_user.followed?(user)
followed = current_user.follow_user_ids.include?(user.id)
opts[:class] ||= 'btn btn-primary btn-block'
class_names = "button-follow-user #{opts[:class]}"
icon = '<i class="fa fa-user"></i>'
Expand Down
17 changes: 0 additions & 17 deletions app/models/concerns/likeable.rb

This file was deleted.

5 changes: 2 additions & 3 deletions app/models/reply.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
class Reply < ApplicationRecord
include MarkdownBody
include SoftDelete
include Likeable
include Mentionable
include MentionTopic

Expand Down Expand Up @@ -98,9 +97,9 @@ def default_notification
def notification_receiver_ids
return @notification_receiver_ids if defined? @notification_receiver_ids
# 加入帖子关注着
follower_ids = self.topic.try(:follower_ids) || []
follower_ids = self.topic.try(:follow_by_user_ids) || []
# 加入回帖人的关注者
follower_ids = follower_ids + (self.user.try(:follower_ids) || [])
follower_ids = follower_ids + (self.user.try(:follow_by_user_ids) || [])
# 加入发帖人
follower_ids << self.topic.try(:user_id)
# 去重复
Expand Down
Loading

0 comments on commit 1833182

Please sign in to comment.