【问题标题】:Calculating karma from upvotes/downvotes on a user's posts根据用户帖子的赞成/反对票计算业力
【发布时间】:2013-10-07 05:07:00
【问题描述】:

我有一个用户和帖子模型,并且正在使用acts_as_votable gem(它给我一个“投票”表)来支持/反对一个帖子。我想为每个用户分配业力,其中业力是用户从他/她的所有帖子中获得的赞成票数减去反对票的总数。

目前我在用户模型上有这个实例方法来计算业力:

  def karma
    count = 0
    self.posts.each do |post|
      count += post.upvotes.size - post.downvotes.size
    end
    return count
  end

我不认为上面的运行时间为 O(2n) 时效率很高,因为对于每个帖子都需要两个额外的数据库查询,一个用于赞成票,一个用于反对票。

关于如何将以上内容组合成一个查询或以其他方式使其更高效的任何想法?

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    不仅效率,这样的设计在OOP方面也不好。 User 模型考虑的太多超出了它的范围。 Karma 是属于用户的东西,不应与其他任何东西捆绑在一起。

    更好的方法是将“Karma”与 Post 分开。

    # Add a "karma" column
    $ rails g migration AddKarmaToUser
    
    # Or use a dedicated table
    class User < ActiveRecord::Base
      has_one :karma
    

    然后,使用控制器或服务对象来改变业力。为简单起见,我将在这里介绍 Controller。不要使用模型回调,因为那是跨模型。

    class PostsController < ApplicationController
      def upvote
        post = Post.find(params[:id])
        post.upvote # pseudo API of acts_as_votable
        current_user.increase_karma
      end
    
      def downvote
        # ...
        current_user.decrease_karma
      end
    end
    
    # Model
    class User < ActiveRecord::Base
      attr_accessible :karma
    
      def increase_karma(count=1)
        update_attribute(:karma, karma + count)
      end
    
      def descrease_karma(count=1)
        # ...
      end
    end
    
    # View
    user.karma
    

    【讨论】:

    • 什么意思,“......这样的设计在OOP方面不好。用户模型考虑的太多超出了它的范围。”这是糟糕的设计,因为我试图访问不属于 User 模型而是属于 Post 模型的投票,还是因为我正在访问由关系定义的帖子,而不是 Users 表上的实际属性? user.posts 没问题,但 user.posts.first.votes 不好?还是他们都不好?另外,目前我有一个单独的 votes_controller。像你上面演示的那样在 posts_controller 中进行投票操作是否更安静?
    • 史蒂夫,对于你的第一个陈述,是的,user.posts 可以,但user.posts.first.votes 不好。这个用户的手太长了 :) 他触摸了不属于他的东西。对于投票,我认为将它们放在 PostsController 中更自然。即使你有更多的投票给其他人说评论,你也可以在 CommentsController 中为 cmets 投票。
    猜你喜欢
    • 2012-12-15
    • 2019-03-10
    • 1970-01-01
    • 2017-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-08
    • 1970-01-01
    相关资源
    最近更新 更多