【问题标题】:How to calculate users response rate and time如何计算用户响应率和时间
【发布时间】:2013-09-19 14:11:16
【问题描述】:

我一直在尝试集思广益,讨论如何计算用户响应率(对收到的消息的响应百分比)和时间(用户对消息的响应速度)。此信息将显示在用户个人资料上。我想不出一个适用于此的公式,也没有看到任何其他有关它的帖子。

例如,用户 A 的回复率为 85%,他们的回复时间为 3 天。攻击这个的正确方法是什么?

消息模型:

    attr_accessible :subject, :body, :sender_id, :recipient_id, :read_at,:sender_deleted,:recipient_deleted
    validates_presence_of :subject, :message => "Please enter message title"
    has_many :notifications, as: :event
  scope :unread, -> {where('read_at IS NULL')}

    belongs_to :sender,
    :class_name => 'User',
    :foreign_key => 'sender_id'
    belongs_to :recipient,
    :class_name => 'User',
    :foreign_key => 'recipient_id'


    # Based on if a message has been read by it's recipient returns true or false.
    def read?
        self.read_at.nil? ? false : true
    end


    def self.received_by(user)
       where(:recipient_id => user.id)
     end


     def self.not_recipient_deleted
       where("recipient_deleted = ?", false)
     end

     def self.sent_by(user)
        Message.where(:sender_id => user.id)
      end

控制器:

  before_filter :set_user

  def index
    @messages = Message.scoped
    @message = Message.new
    if params[:mailbox] == "sent"
      @messages = @user.sent_messages.paginate :per_page => 10, :page => params[:page], :order => "created_at DESC"
    elsif params[:mailbox] == "inbox"
      @messages = @user.received_messages.paginate :per_page => 10, :page => params[:page], :order => "created_at DESC"
    #elsif params[:mailbox] == "archived"
     # @messages = @user.archived_messages
    end
    if params[:mailbox] == "unread"
    @messages = @user.unread_messages.paginate :per_page => 10, :page => params[:page], :order => "created_at DESC"
  end
  if params[:mailbox] == "trash"
    @messages = @user.deleted_messages.paginate :per_page => 10, :page => params[:page], :order => "created_at DESC"
  end
  end

  def new
      @message = Message.new
      @message.conversation_id = params[:conversation_id]
    end

    def create
      @message = Message.new(params[:message])
      @message.sender_id = @user.id
      if @message.save
        flash[:notice] = "Message has been sent"
        redirect_to user_messages_path(current_user, :mailbox=>:inbox)
      else
        render :action => :new
      end
    end

    def show
      @reply_message = Message.new
        @message = Message.find(params[:id])
        if @message.recipient == current_user
           UserMessageWorker.perform_async(@message.id, current_user.id)
         end
        @message.readingmessage if @message.recipient == current_user
      end

    def reply
        @reply_message = Message.new
        @message = Message.new
        @message.conversation_id = params[:conversation_id]
    end

   def destroy
     @message = Message.find(params[:id])
     @message.destroy
     flash[:notice] = "Successfully deleted message."
     redirect_to user_messages_path(@user, @messages)
   end

  def delete_multiple
      if params[:delete]
        params[:delete].each { |id|
          @message = Message.find(id)
          @message.mark_message_deleted(@message.id,@user.id) unless @message.nil?
        }
        flash[:notice] = "Messages deleted"
      end
      redirect_to user_messages_path(@user, @messages)
  end


  def update
      @message = Message.new
      if params[:reply_to]
        @reply_to = User.find_by_id(params[:reply_to])
        unless @reply_to.nil?
          @message.recipient_id = @reply_to.id
        end
      end
    end

  private
    def set_user
      @user = current_user
  end
end

日志:

2014-02-05T17:08:16Z 33906 TID-zt6cxk WARN: {"retry"=>true, "queue"=>"default", "class"=>"UserMessageWorker", "args"=>[159, 2], "jid"=>"f502221628588feaa5efa7d3", "enqueued_at"=>1391619720.3566332, "error_message"=>"undefined method `messages' for #<User:0x00000101edb0a0>", "error_class"=>"NoMethodError", "failed_at"=>"2014-02-05T17:02:00Z", "retry_count"=>4, "retried_at"=>2014-02-05 17:08:16 UTC}
2014-02-05T17:08:16Z 33906 TID-zt6cxk WARN: undefined method `messages' for #<User:0x00000101edb0a0>
2014-02-05T17:08:16Z 33906 TID-zt6cxk WARN: /Users/.rvm/gems/ruby-2.0.0-p353/gems/activemodel-4.0.0.rc1/lib/active_model/attribute_methods.rb:436:in `method_missing'
/Users/.rvm/gems/ruby-2.0.0-p353/gems/activerecord-4.0.0.rc1/lib/active_record/attribute_methods.rb:131:in `method_missing'
/Users/dating/app/workers/user_message_worker.rb:8:in `perform'
/Users/.rvm/gems/ruby-2.0.0-p353/gems/sidekiq-2.17.2/lib/sidekiq/processor.rb:49:in `block (3 levels) in process'
/Users/.rvm/gems/ruby-2.0.0-p353/gems/sidekiq-2.17.2/lib/sidekiq/middleware/chain.rb:122:in `call'
/Users/.rvm/gems/ruby-2.0.0-p353/gems/sidekiq-2.17.2/lib/sidekiq/middleware/chain.rb:122:in `block in invoke'
/Users/.rvm/gems/ruby-2.0.0-p353/gems/sidekiq-2.17.2/lib/sidekiq/middleware/server/active_record.rb:6:in `call'
/Users/.rvm/gems/ruby-2.0.0-p353/gems/sidekiq-2.17.2/lib/sidekiq/middleware/chain.rb:124:in `block in invoke'
/Users/.rvm/gems/ruby-2.0.0-p353/gems/sidekiq-2.17.2/lib/sidekiq/middleware/server/retry_jobs.rb:62:in `call'
/Users/.rvm/gems/ruby-2.0.0-p353/gems/sidekiq-2.17.2/lib/sidekiq/middleware/chain.rb:124:in `block in invoke'
/Users/.rvm/gems/ruby-2.0.0-p353/gems/sidekiq-2.17.2/lib/sidekiq/middleware/server/logging.rb:11:in `block in call'
/Users/.rvm/gems/ruby-2.0.0-p353/gems/sidekiq-2.17.2/lib/sidekiq/logging.rb:22:in `with_context'
/Users/.rvm/gems/ruby-2.0.0-p353/gems/sidekiq-2.17.2/lib/sidekiq/middleware/server/logging.rb:7:in `call'
/Users/.rvm/gems/ruby-2.0.0-p353/gems/sidekiq-2.17.2/lib/sidekiq/middleware/chain.rb:124:in `block in invoke'
/Users/.rvm/gems/ruby-2.0.0-p353/gems/sidekiq-2.17.2/lib/sidekiq/middleware/chain.rb:127:in `call'
/Users/.rvm/gems/ruby-2.0.0-p353/gems/sidekiq-2.17.2/lib/sidekiq/middleware/chain.rb:127:in `invoke'
/Users/.rvm/gems/ruby-2.0.0-p353/gems/sidekiq-2.17.2/lib/sidekiq/processor.rb:48:in `block (2 levels) in process'
/Users/.rvm/gems/ruby-2.0.0-p353/gems/sidekiq-2.17.2/lib/sidekiq/processor.rb:105:in `stats'
/Users/.rvm/gems/ruby-2.0.0-p353/gems/sidekiq-2.17.2/lib/sidekiq/processor.rb:47:in `block in process'
/Users/.rvm/gems/ruby-2.0.0-p353/gems/sidekiq-2.17.2/lib/sidekiq/processor.rb:86:in `do_defer'
/Users/.rvm/gems/ruby-2.0.0-p353/gems/sidekiq-2.17.2/lib/sidekiq/processor.rb:37:in `process'
/Users/.rvm/gems/ruby-2.0.0-p353/gems/celluloid-0.15.2/lib/celluloid/calls.rb:25:in `public_send'
/Users/.rvm/gems/ruby-2.0.0-p353/gems/celluloid-0.15.2/lib/celluloid/calls.rb:25:in `dispatch'
/Users/.rvm/gems/ruby-2.0.0-p353/gems/celluloid-0.15.2/lib/celluloid/calls.rb:122:in `dispatch'
/Users/.rvm/gems/ruby-2.0.0-p353/gems/celluloid-0.15.2/lib/celluloid/actor.rb:322:in `block in handle_message'
/Users/.rvm/gems/ruby-2.0.0-p353/gems/celluloid-0.15.2/lib/celluloid/actor.rb:416:in `block in task'
/Users/.rvm/gems/ruby-2.0.0-p353/gems/celluloid-0.15.2/lib/celluloid/tasks.rb:55:in `block in initialize'
/Users/.rvm/gems/ruby-2.0.0-p353/gems/celluloid-0.15.2/lib/celluloid/tasks/task_fiber.rb:13:in `block in create'

【问题讨论】:

  • 所以您要通过电子邮件将用户发送回您的网站,并且您想要计算经过的时间间隔,以及向查看该页面的人发送电子邮件的响应率?
  • 对于注册用户,我无法创建一个公式/代码来计算他们对收到的消息(未读)的响应率。它应该显示响应率为 %,响应时间为 x 天。例如在airbnb.com/rooms/1349952 上,它会在他们的联系信息下显示响应率和时间。
  • 如何确定一条消息是对另一条消息的响应?
  • 它将基于收件人对发件人未读邮件的响应。这只会计算原始消息,而不是回复。

标签: ruby-on-rails


【解决方案1】:

我假设您希望将这些值存储在 User 表中?我将这些列称为average_response_timeresponse_rate。您还需要在 User 表中添加一列,该列是从发送消息到看到消息之间的所有时间的总和。我就叫它response_total

然后把它全部放在后台工作中......或者不,但我愿意。我喜欢 Sidekiq,关于它有一个很棒的 railscast here

在消息控制器中

def show
  @message = Message.find(params[:id])
  if @message.recipient == current_user
    UserMessageWorker.perform_async(@message.id, current_user.id)
  end
end

然后在 app/workers/user_message_worker.rb 中

class UserMessageWorker
  include Sidekiq::Worker

  def perform(message_id, user_id)
    message = Message.find(message_id)
    user = User.find(user_id)
    message.read_at = Time.now
    old_msg_count = user.messages.count

    if message.save
      msg_response_time = message.read_at - message.created_at

      response_rate = (user.messages.where("read_at IS NOT NULL").count)/(old_msg_count + 1)
      response_time = ((user.average_response_time * old_msg_count)+msg_response_time)/(old_msg_count + 1)
      user.update_attributes(:response_rate => response_rate, :average_response_time => average_response_time )
    end
  end
end

我很确定我对 response_time 的数学运算是正确的,但您应该仔细检查一下。此外,根据您想要的准确度,您可能希望在几分钟或几秒钟(或几小时或几天)内存储response_total,这样数字就不会变得很大。

【讨论】:

  • 如果您不想使用sidekiq,您可以将perform 方法中的所有代码移动到调用perform_async 的控制器show 操作中。如果您确实记得更改 messageuser 变量。
  • 感谢您的帮助!
猜你喜欢
  • 2022-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多