docbrown/app/controllers/reactions_controller.rb
Andy Zhao 5ace9a5fc9 Organization Notifications (#1762)
* Add spec for org reaction notification

* Add organization_id to notifications

* Add validations for user and org IDs

* Move comment json_data out of loop

* Use actual column names instead

* Add organization filters

* Remove extra text-align

* Add organization filtering

* Refactor to reduce complexity

* Add receiver argument to handle orgs

* Add has_many notifications for orgs

* Add follow notifications for orgs

* Add comment notifications for orgs

* Rename some tests for specificity

* Add mark org notifications as read functionality

* Add radix to parseInt

* Define json_data outside of loop

* Notify org followers of a new post as well

* Move test to proper location

* Add test for aggregated method

* Make send org reaction notification more readable

* Test the rest of the notification model

* Refactor tag adjustment spec

* Fix extra html
2019-02-25 14:25:37 -08:00

86 lines
3.2 KiB
Ruby

class ReactionsController < ApplicationController
before_action :set_cache_control_headers, only: [:index], unless: -> { current_user }
after_action :verify_authorized
def index
skip_authorization
add_param_context(:article_id)
if params[:article_id]
id = params[:article_id]
reactions = if efficient_current_user_id.present?
Reaction.where(reactable_id: id,
reactable_type: "Article",
user_id: efficient_current_user_id).
where("points > ?", 0)
else
[]
end
render json:
{
current_user: { id: efficient_current_user_id },
article_reaction_counts: Reaction.count_for_article(id),
reactions: reactions
}.to_json
else
add_param_context(:commentable_id, :commentable_type)
comments = Comment.where(
commentable_id: params[:commentable_id],
commentable_type: params[:commentable_type],
).select(%i[id positive_reactions_count])
comment_ids = comments.map(&:id)
reaction_counts = comments.map { |c| { id: c.id, count: c.positive_reactions_count } }
reactions = current_user ? cached_user_positive_reactions(current_user).where(reactable_id: comment_ids) : []
render json:
{
current_user: { id: current_user&.id },
positive_reaction_counts: reaction_counts,
reactions: reactions
}.to_json
end
set_surrogate_key_header params.to_s unless current_user
end
def create
authorize Reaction
add_param_context(:reactable_id, :reactable_type, :category)
Rails.cache.delete "count_for_reactable-#{params[:reactable_type]}-#{params[:reactable_id]}"
category = params[:category] || "like"
reaction = Reaction.where(
user_id: current_user.id,
reactable_id: params[:reactable_id],
reactable_type: params[:reactable_type],
category: category,
).first
if reaction
reaction.user.touch
reaction.destroy
Notification.send_reaction_notification_without_delay(reaction, reaction.reactable.user)
Notification.send_reaction_notification_without_delay(reaction, reaction.reactable.organization) if organization_article?(reaction)
@result = "destroy"
else
reaction = Reaction.create!(
user_id: current_user.id,
reactable_id: params[:reactable_id],
reactable_type: params[:reactable_type],
category: category,
)
@result = "create"
Notification.send_reaction_notification(reaction, reaction.reactable.user)
Notification.send_reaction_notification(reaction, reaction.reactable.organization) if organization_article?(reaction)
end
render json: { result: @result, category: category }
end
def cached_user_positive_reactions(user)
Rails.cache.fetch("cached_user_reactions-#{user.id}-#{user.updated_at}", expires_in: 24.hours) do
Reaction.where(user_id: user.id).
where("points > ?", 0)
end
end
private
def organization_article?(reaction)
reaction.reactable_type == "Article" && reaction.reactable.organization_id
end
end