如何在每个用户后面接收一个应用程序通知?

时间:2017-05-29 05:26:37

标签: ruby-on-rails ruby

我最近完成了一个应用内通知,尽管实施存在很大的缺陷。当向已经成功激活其帐户的所有用户发送激活消息时,当一个用户跟随最终用户时,它变得有点复杂。当当前用户跟随并取消关注几次时,最终用户会从当前用户获得多个通知。当当前用户取消关注最终用户时,如何销毁通知,停止发送多个"当前用户开始关注您"通知给最终用户?

用户模型

class User < ActiveRecord::Base
  searchkick word_start: [:name, :surname] 

  has_many :active_relationships,  class_name:  "Relationship",
                                   foreign_key: "follower_id",
                                   dependent:   :destroy
  has_many :passive_relationships, class_name:  "Relationship",
                                   foreign_key: "followed_id",
                                   dependent:   :destroy
  has_many :following, through: :active_relationships,  source: :followed
  has_many :followers, through: :passive_relationships, source: :follower
  has_many :notifications, foreign_key: :recipient_id 

...

  # Follows a user.
  def follow(other_user)
    following << other_user
  end

  # Unfollows a user.
  def unfollow(other_user)
    following.delete(other_user)
  end

  # Returns true if the current user is following the other user.
  def following?(other_user)
    following.include?(other_user)
  end

...

关系模型

 class Relationship < ActiveRecord::Base

    belongs_to :follower, class_name: "User"
    belongs_to :followed, class_name: "User"
    validates  :follower_id, presence: true
    validates  :followed_id, presence: true

 end

通知模型

class Notification < ActiveRecord::Base

  belongs_to :recipient, class_name: "User"
  belongs_to :actor, class_name: "User"
  belongs_to :notifiable, polymorphic: true

  scope :unread, ->{ where(read_at: nil) }
  scope :recent, ->{ order(created_at: :desc).limit(5) }

end

关系控制器

 class RelationshipsController < ApplicationController
 before_action :logged_in_user

  def create 
    @user = User.find(params[:followed_id])
    current_user.follow(@user)  
    Notification.create(recipient: @user, actor: current_user, action: "following", notifiable: @user)
    respond_to do |format|
      format.html { redirect_to @user }
      format.js
    end
  end

  def destroy
    @user = Relationship.find(params[:id]).followed
    current_user.unfollow(@user)
    # Where the notification should be destroyed
    respond_to do |format|
      format.html { redirect_to @user }
      format.js
    end
  end
end

1 个答案:

答案 0 :(得分:2)

这取决于您实施关系模型的方式。

我只会在创建关系时发送电子邮件。如果用户取消关注另一个用户,我不会删除该关系,而是将其标记为取消关注。如果用户决定再次关注同一用户,则只需删除标记关系为非活动状态的标志。这意味着您不会创建新关系,因此您无需发送电子邮件。

首先,您需要在active模型中添加Relationship布尔标志。这可以通过这样的迁移完成:

def change 
  add_column :relationships, :active, :boolean, default: true
end

然后,您需要尊重关联和范围中的active标志:

has_many :following, 
  -> { Relationship.where(active: true) },
  through: :active_relationships,  source: :followed
has_many :followers, 
  -> { Relationship.where(active: true) },
  through: :passive_relationships, source: :follower

接下来,更改followunfollow方法:

def follow(other_user)
  relationship = Relationship.where(
    followed_id: other_user.id, follower_id: self.id
  ).first

  if relationship.present?
    relationship.update(active: true) 
  else
    following << other_user

    Notification.create(
      action:     'following', 
      actor:      self, 
      notifiable: other_user,
      recipient:  other_user
    )
  end
end

def unfollow(other_user)
  relationship = Relationship.where(
    followed_id: other_user.id, follower_id: self.id
  )

  relationship.update(active: false) if relationship.present?
end

def following?(other_user)
  Relationship.exists?(
    followed_id: other_user.id, follower_id: self.id, active: true   
  )
end

请注意,现在Notification方法中创建了follow。这样可以简化控制器:

def create 
  @user = User.find(params[:followed_id])
  current_user.follow(@user)  

  respond_to do |format|
    format.html { redirect_to @user }
    format.js
  end
end

def destroy
  @user = Relationship.find(params[:id]).followed
  current_user.unfollow(@user)

  respond_to do |format|
    format.html { redirect_to @user }
    format.js
  end
end