0

ユーザーが投稿できるアプリがあります。各投稿は賛成票と反対票を投じることができます。各ユーザーの評判は、投稿の賛成票と反対票から計算されます。現在、各投稿の賛成票と反対票を2か所で追跡しています。まず、私の投稿テーブルがあります:

 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

私はもともと、特定の投稿の投票数をより効率的に照会できるように、2つの異なるテーブルで投稿の投票を追跡していました。たとえば、次のようになります。

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

「賛成」と「反対」の列を保持するか、それらを削除して「投票」テーブルを使用して投稿の評判を計算する方がよいでしょうか。

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.countandを使用します。Post.votes.down_votes.count

あなたが概説したアプローチは、私がSQLでそれに取り組むために使用した方法です。上記は、よりレールスタイルのアプローチです。適切なデータベース移行を追加する必要があります。

于 2012-09-23T19:16:48.443 に答える