Rails关联 - 用户通过评论有很多用户

时间:2014-02-16 03:17:53

标签: ruby-on-rails associations

我正在尝试设计一个评论系统,允许用户通过评论在其他用户的页面上发帖。

用户将对其页面发表评论,该评论由另一位名为“评论者”的用户发布。

1)以下代码是否合法/功能/体面设计?

2)重新命名的“评论者”用户和未重命名的“用户”是否可以,或者是否应始终在语义上重命名用户的所有关联名称?

3)是否有更好的方法来实现这种设计意图(例如,没有通过以下方式执行has_many)?

class User < ActiveRecord::Base
  has_many :comments
  has_many :users,      through: :comments
  has_many :commenters, through: :comments, class_name: 'User'  
end

class Comment < ActiveRecord::Base
  belongs_to :user
  belongs_to :commenter, class_name: 'User'
end

注:

我希望允许用户对其他模特(例如角色,名人)发表评论。因此,我认为需要在各种has_many通过关联中使用注释表。

用户通过评论有很多评论者 人物通过评论有很多评论者 名人通过评论有很多评论者

3 个答案:

答案 0 :(得分:4)

我相信你的设计无法正常工作 - 你将has_many与has_many混合使用。如果我是你,我会使用像这样的方法:

class User < ActiveRecord::Base
  has_many :owned_comments, class_name: 'Comments', foreign_key: 'owner_id'
  has_many :posted_comments, class_name: 'Comments', foreign_key: 'commenter_id'
end

class Comment < ActiveRecord::Base
  belongs_to :owner, class_name: 'User'
  belongs_to :commenter, class_name: 'User'
end

答案 1 :(得分:1)

必须尝试使用​​acts_as_commentable gem它会提供很多其他选项以及公共,私人评论https://github.com/jackdempsey/acts_as_commentable

答案 2 :(得分:1)

我在mongoid和rails中实现了类似的功能。模型是用户,友谊和请求。就像用户向其他用户发送好友请求一样。

class User
  include Mongoid::Document
  include Mongoid::Timestamps
  devise :invitable, :database_authenticatable, :registerable, :recoverable,
    :rememberable, :trackable, :validatable, :confirmable
  ...
  has_many :requests_from, class_name: "Request", inverse_of: :requested_by
  has_many :requests_to, class_name: "Request", inverse_of: :requested_to
  has_many :friendships, inverse_of: :owner

  def friends
    #retrive all the friendships and collect users have sent me a request or being sent a request.
    fs = Friendship.any_of({:friend_id.in => [self.id]}, {:owner_id.in => [self.id]}).where(state: 'accepted')
    User.in(id: fs.collect{|i| [i.friend_id, i.owner_id]}.flatten - [self.id])
  end
end#User

class Friendship
  include Mongoid::Document
  include Mongoid::Timestamps

  field :state, type: String, default: 'pending'
  field :pending, type: Boolean, default: true

  belongs_to :owner, class_name: 'User'
  belongs_to :friend, class_name: "User"

  validates :state, inclusion: { in: ["pending", "accepted", "rejected"]}
  ...
end#Friendship

class Request
  include Mongoid::Document
  include Mongoid::Timestamps

  field :state, type: String, default: 'pending'

  belongs_to :requested_by, class_name: 'User', inverse_of: :requests_from
  belongs_to :requested_to, class_name: 'User', inverse_of: :requests_to

  validates :state, inclusion: { in: ["pending", "accepted", "rejected"]}
  ...
end#Request

我希望这会有所帮助。