Let's say that I'm building an engine that has many blogs and many users. Users can have many blogs and blogs can have many users (users hasAndBelongsToMany blogs). I would create a pivot table called users_blogs which would look like this:
id user_id blog_id role
1 1 1 admin
2 1 2 poster
3 2 2 admin
So, user 1 belongs to blogs 1 and 2, and user 2 belongs to blog 2. User 1 is an admin in blog 1, and a poster in blog 2, and user 2 is an admin in blog 2.
There will also be posts. users_blogs will have many posts, and posts can have many users_blogs. They would be joined with a pivot table that would look like this:
id users_blog_id post_id
1 2 1
2 3 1
So, referring to users_blogs, user 1 on blog 2 collaborated with user 2 on blog 2 to create post开发者_运维问答 1.
I'm relatively new to MVC, so I'm wondering if A) the "role" data in the first table is where it's supposed to be?, and B) Is there a more correct way to do this structure? Frameworks will do the magic for me, I just want to make sure that this makes sense, and I've got the correct naming conventions. I'm using Cakephp, but I also think that this question could be answered by a Rails programmer.
Thank you!
It looks like you're on the right track. If I understand you, this is how it should be:
I didn't completely understand one of your statements, so I'm going on the assumption that a post
belongsTo
a single blog
like most.
First issue is, your "pivot table" naming convention must be in alphabetical order - so it should be blogs_users
, not users_blogs
. Seems minor, but won't work otherwise.
Associations:
blog hasMany post
post belongsTo blog
user hasAndBelongsToMany blog //allowing more than one user to be associated to a blog
blog hasAndBelongsToMany user
user hasAndBelongsToMany post //allowing more than one user to be associated to a post
post hasAndBelongsToMany user
role hasAndBelongsToMany user //better to keep roles in a table that just a string
user hasAndBelongsToMany role //use 'with'=>'blogs_users' in your association
between user/roll
Tables:
users (id, name, ...etc)
blogs (id, title, ...etc)
roles (id, role)
blogs_users (id, user_id, role_id, blog_id)
posts (id, title, blog_id)
posts_users (id, post_id, user_id)
Update:
I'm not the best at this - still somewhat learning myself, but - off the top of my head, you could get the posts from blog 1 created by user 1 via something like this:
$blogId = '1';
$userId = '1';
$posts = $this->Post->find('all', array(
'conditions' => array(
'User.id' => $userId,
'Blog.id' => $blogId
)
);
This isn't really a rails, cakephp or mvc question but your relational database schema looks as it should based on what you described.
I don't know about Cakephp, but there are three problems about you join table which will break a habtm relationship in Rails.
1) The join table is named blogs_users
, by default.
2) The join table must not have any other attributes, such as role
.
3) The join table must not have an id
.
So your blogs_users
table should have only blog_id
and user_id
, otherwise you'll get errors.
If you want your join table to be a full fledged model in Rails, you'll want to use a has_many :through
relationship. So
class User
has_many :user_blogs
has_many :blogs, :through => :user_blogs
end
class UserBlog
belongs_to :blog
belongs_to :user
validates_presence_of :role, :in => ALLOWED_ROLE_NAMES # Example of logic in this model
end
class Blog
has_many :user_blogs
has_many :users, :through => :user_blogs
end
精彩评论