问题
I'm trying to design a comment system allowing users to post on other users' pages, through comments.
A user will have a comment on his page, which is posted by another user called "commenter."
1) Is the following code legit/functional/decent design?
2) Is it OK to have a renamed "commenter" user, in conjunction with an un-renamed "user", or should all association names of user always be renamed semantically?
3) Are there better ways to implement this design intent (e.g. not doing a has_many through:)?
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
NOTE:
I wish to allow users to comment on users, but also on other models, (e.g. characters, celebrities). So I would think having the comments table be used in various has_many through associations is called for.
users has many commenters through comments characters has many commenters through comments celebrities has many commenters through comments
回答1:
I believe your design is not going to work as it is - you are mixing has_many with has_many through. If I were you I would use an approach like this one:
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
回答2:
have to tried acts_as_commentable gem it give lot of other options as well like public,private comment https://github.com/jackdempsey/acts_as_commentable
回答3:
I implemented a similar functionality in mongoid and rails. The models were User, Friendship and Request. Its like User sends friend request to another user.
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
I hope this helps.
来源:https://stackoverflow.com/questions/21806860/rails-associations-users-has-many-users-through-comments