在Rails中关联Post,Comment,User和Vote模型的有效方法是什么?

时间:2012-02-01 22:54:35

标签: ruby-on-rails

现在,我有三个模型Post,Comment和User(使用 Devise )关联如下:

post.rb:

class Post < ActiveRecord::Base
  attr_accessible :title, :content, :total_votes

  validates :title,   :presence => true,
                      :length   => { :maximum => 30 },
                      :uniqueness => true
  validates :content, :presence => true,
                      :uniqueness => true

  belongs_to :user
  has_many :comments, :dependent => :destroy
end

comment.rb:

class Comment < ActiveRecord::Base
  attr_accessible :content, :user_id

  belongs_to :post, :counter_cache => true
  belongs_to :user
end

user.rb:

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable,
         :omniauthable
  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :password, :password_confirmation, :remember_me, :username

  validates_presence_of :username
  has_many :posts, :dependent => :destroy
  has_many :comments, :dependent => :destroy

  def self.find_for_facebook_oauth(access_token, signed_in_resource=nil)
    data = access_token.extra.raw_info
    if user = User.where(:email => data.email).first
      user
    else # Create a user with a stub password. 
      User.create!(:email => data.email, :password => Devise.friendly_token[0,20]) 
    end
  end
end

我想添加第四个名为投票的模型,其中包含以下条件:

  1. 帖子评论都可以投票(上下)并显示总金额/总和。
  2. 每个帖子将有很多票数(上下)并显示总票数/总和。
  3. 每个评论都会有很多选票
  4. 每次投票时都应存储用户的ID,这样我就可以限制每位用户投票一次,并显示投票用户的ID /名称(不知道在哪里存储)
  5. 现在,我不确定这是否是使用多态关联和/或计数器缓存的好机会。

    关联这些帖子,评论,用户和投票模型的有效方法是什么? (如果可能的话,我想看看迁移的样子)

1 个答案:

答案 0 :(得分:1)

这是polymorphic association有用的完美教科书示例。

您的votes表格迁移如下所示:

create_table :votes do |t|
  t.references :votable, :polymorphic => true
  t.references :user
  t.integer :polarity
  t.integer :total
end

这会创建一个包含此架构的表:

id INTEGER
votable_id INTEGER
votable_type VARCHAR
user_id INTEGER
polarity INTEGER
total INTEGER

在这里,user_id将是投票的人,polarity对于upvote是'1'或对于downvote是'-1'(这可以让你只需将极性加总为得到upvotes和downvotes取消),votable_type将包含投票的内容(PostComment),votable_id将包含投票所针对的内容的ID ,total将保持总投票金额(效率)。

然后你的模型看起来像这样:

class Vote < ActiveRecord::Base
    belongs_to :votable, :polymorphic => true
    belongs_to :user

    before_create :update_total

    protected

    def update_total
        self.total ||= 0
        self.total += self.polarity
    end
end

class Post < ActiveRecord::Base
    has_many :votes, :as => :votable
end

class Comment < ActiveRecord::Base
    has_many :votes, :as => :votable
end

class User < ActiveRecord::Base
    has_many :votes
end