Figuring out Rails associations
In brief: I'm new to rails and am seeking some help regarding the correction way to associate models.
Background: I am working on a system to manage the review process of academic journals. This process is something like this:
User submits a Submission that contains a Version. The Submission contains all the stuff that only needs to be input once (title, cover letter), while the Version is the actual paper being submitted for consideration.
One or more Reviewers is allocated to a Submission.
Each Reviewer assigned to a Submission then writes a Review for that particular Submission, which encompasses a decision (accept/reject) and some feedback.
Based on the Review(s), an Admin sets the status of the Submission (accept/reject).
the User can then choose to submit a new Version for consideration and the process is repeated from step 2.
Question:
So firstly, Submissions has_many Versions belongs_to a Submission, which I have implemented and it works fine.
I'm wondering exactly how the rest of it should be structured. Could those of you more experience share your thoughts on what I think I am meant to do next?
I initially thought a Submission has_many Reviewers. But it seems it should actually be the other way around --- Reviewer is assigned many Submissions. To illustrate, it's a bit like giving individual Reviewers permission to comment on specific posts. Is this a normal has_many relationship? I've been reading http://guides.rubyonrails.org/association_basics.html and it seems like it could also be开发者_开发知识库 a has_and_belongs_to_many.
Each Version has many Reviews, therefore Version has_many Reviews and Review belongs_to Version.
Additionally, I guess Review should have some reviewer_id kind if field so we know who wrote it. This should be a Review has_one Reviewer.
As an aside, I don't want to be too needy, but it would be absolutely fantastic if someone could provide some insight into the few lines of Reviewer controller code necessary for an admin to assign him/her to a Submission.
Cheers,
I would do something like this:
#reviewer.rb the user who reviews your versions
class Reviewer < ActiveRecord::Base
has_many :reviews
end
#review.rb the actual review
class Review < ActiveRecord::Base
belongs_to :reviewer
belongs_to :version
#usually put here a field called comment:string
end
class Version < ActiveRecord::Base
has_many :reviews
has_many :reviewers, :through => :reviews, :uniq=>true #this will give you the list of reviewers
belongs_to :submission
end
class Submission < ActiveRecord::Base
has_many :versions
end
Let me know if you need any clarification.
Update
In many cases your reviewer could be a user model so instead of reviewer you can use a user model, and then name it properly to keep the meaning of relations. These changes are needed.
class User < ActiveRecord::Base
has_many :reviews
end
class Review < ActiveRecord::Base
belongs_to :reviewer, :class_name=>'User'
belongs_to :version
#usually put here a field called comment:string
end
Then as suggested by @Andy Waite use the devise
gem to authenticate your users.
You need a many-to-many join model between Submission and Reviewer. You could call this an Allocation:
- belongs_to :submission
- belongs_to :reviewer
- has_many :reviews
Then the Review model could be:
- belongs_to :allocation
- belongs_to :version
- review
- decision
- feedback
I think that gives everything you need.
精彩评论