0

我有一个允许用户发布的应用程序。每个帖子都可以被赞成和反对。每个用户还具有根据其帖子的赞成票和反对票计算的声誉。现在,我在两个地方跟踪每个帖子的赞成票和反对票。首先,有我的帖子表:

 create_table "posts", :force => true do |t|
    t.integer  "user_id"
    t.text     "content"
    t.integer  "upvotes",    :default => 0
    t.integer  "downvotes",  :default => 0
    t.datetime "created_at",                :null => false
    t.datetime "updated_at",                :null => false
  end

我还使用单独的“投票”表跟踪每个投票,以便我知道哪个用户已经对帖子进行了投票(0 票是没有投票,1 票是反对票,2 票是赞成票):

create_table "votes", :force => true do |t|
    t.integer  "user_id"
    t.integer  "post_id"
    t.integer  "vote",       :default => 0
    t.datetime "created_at",                :null => false
    t.datetime "updated_at",                :null => false
  end

我最初在两个不同的表中跟踪帖子投票,以便更有效地查询特定帖子的投票数,例如:

post_reputation = post.upvotes - post.downvotes

但是,我现在认为这是一种不好的做法,我应该删除“帖子”表上的“赞成票”和“反对票”列,以免重复投票数据。然后我会计算帖子声誉做这样的事情:

def calculate_post_reputation(post_id)
  some_post = Post.find(post_id)
  vote_count = 0
  some_post.votes.each do |vote|
    if vote.vote.to_i == 2
      vote_count += 1
    elsif vote.vote.to_i == 1
      vote_count -= 1
    end
   end
  vote_count
end

保留“upvotes”和“downvotes”列还是删除它们并使用“votes”表来计算帖子声誉更好?

4

1 回答 1

0

我会考虑(伪代码):

Models:

class User < ActiveRecord::Base
  has_many :votes
  has_many :posts, :through => votes

class Post < ActiveRecord::Base
  has_many :votes
  has_many :users, :though => :votes

class Vote < ActiveRecord::Base
  belongs_to :user
  belongs_to :post
  attr_accessor :direction
  UP='Up'
  DOWN='Down'
  DIRECTIONS=[UP,DOWN]
  validates_inclusion_of :direction, in: [DIRECTIONS]
  scope :up_votes where(:direction => UP) 
  scope :down_votes where(:direction => DOWN)

然后使用Post.votes.up_votes.countPost.votes.down_votes.count表示赞成或反对票的数量。

您概述的方法是我过去在 SQL 中处理它的方法,上面是一种更 Rails 风格的方法。您需要添加适当的数据库迁移。

于 2012-09-23T19:16:48.443 回答