Rails可订阅的通知模型

时间:2015-02-26 14:36:32

标签: ruby-on-rails

我有一些模型,我希望用户能够订阅或取消订阅,即在某些事件发生时选择加入或不接收通知。

例如,我有一个视频模型,用户可以评论和评论。如果用户订阅了视频,他们会在发生某些事情时收到通知(类似于Github)。评论,评论,状态变化等。

我想知道如何根据模型及其相互关系来设置它。

例如,我会创建一个通用的NotificationSubscription模型吗?:

class NotificationSubscription
  belongs_to :subscribable, polymorphic: true
  belongs_to :subscriber, class_name: "User", foreign_key: "user_id"
end

class User
  has_many :notification_subscriptions, dependant: :destroy
end

然后在可订阅的模型中:

class Video
  has_many :notification_subscriptons, as: :subscribable, dependant: :destroy
  has_many :notification_subscribers, through: :notification_subscriptons, source: :subscriber
end

或有疑虑:

module Subscribable
  extend ActiveSupport::Concern

  included do
    has_many :notification_subscriptions, as: :subscribable, dependent: :destroy
    has_many :subscribers, through: notification_subscriptions
  end

  module ClassMethods
  end

  def subscription_for(subscriber)
    subscriber.try(:notification_subscriptions).try(:find_by, subscribable: self)
  end

  def subscribe(subscriber)
    return false if subscription_for(subscriber).present?
    subscription = NotificationSubscription.new(subscribable: self, subscriber: subscriber)
    subscription.save
  end

  def unsubscribe(subscriber)
    subscription = subscription_for(subscriber)
    return false unless subscription.present?
    subscription.destroy
  end
end

class Video
  include Subscribable
end

和notification_subscription架构:

class CreateNotificationSubscriptions < ActiveRecord::Migration
  def change
    create_table :notification_subscriptions do |t|
      t.references :user, index: true
      t.references :subscribable, polymorphic: true, index: true
      t.boolean    :subscribed
      t.boolean    :ignored
      t.string     :reason

      t.timestamps
    end

    add_index :notifications_subscriptions, [:user_id, :subscribable_id, :subscribable_type], unique: true
  end
end

1 个答案:

答案 0 :(得分:1)

我会使用多态关联,但我认为你的措辞有些错误。给出的例子是:

http://guides.rubyonrails.org/association_basics.html#polymorphic-associations

class Picture < ActiveRecord::Base
  belongs_to :imageable, polymorphic: true
end

class Employee < ActiveRecord::Base
  has_many :pictures, as: :imageable
end

class Product < ActiveRecord::Base
  has_many :pictures, as: :imageable
end

它比你的多态代码简单得多。它实际上是你在第一个和第二个例子中所拥有的组合。

稍微偏离主题,但希望这很有用,我会将ActiveSupport::Notifications用于事件本身。通过这种方式,您可以触发事件并让单独的对象订阅该事件,以通过直接电子邮件或通过启动Sidekiq作业来发送订阅者(用户)通知。 http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html