Reputation: 2837
Say I have a blog_posts table. But, the users writing posts belong to groups, and each group has its own blog.
For example:
Say, a user belongs to 3 groups: Marketing, Project Alpha, Administrators
He creates a blog post, but want that post to appear in the "Marketing Blog" and on the "Project Alpha" blog.
What would be the best way to model this?
Would it be a bad idea to have a field in the blog_posts table like: group_ids
and store a comma-delimited list of ids: 3,7 (where Marketing Group =3, and Project Alpha=7)
or should I create another table and store blog_posts id and groups?
Thanks.
Upvotes: 0
Views: 125
Reputation: 4136
Building on @minitech's answer i'd have 3 model's and 5 db tables
Models
rails g model <model_name>
Additional tables
rails g migration <table_name>
Then in your models configure the relations as follows
class Post < ActiveRecord::Base
has_and_belongs_to_many :groups
belongs_to :user
end
class User < ActiveRecord::Base
has_and_belongs_to_many :groups
has_many :posts
end
class Group < ActiveRecord::Base
has_and_belongs_to_many :users
has_and_belongs_to_many :posts
end
Then as per your example the code becomes:
user = User.find(<id of user>)
post = Post.create(:title => 'foo', :content => 'bar', :user => user)
post.groups << Group.find(3)
post.groups << Group.find(7)
Upvotes: 1
Reputation: 18940
Using comma delimited lists as a way around making all data items atomic is a bad idea. It's basically a way of taking data that is not in first normal form and transfomring so that it looks like first normal form data even though it's not.
If you do this, for certain queries you will have to do a full scan of one of the tables instead of an indexed lookup. This will be monstrously slow, and get worse as data volume increases.
A better solution is to have a junction table that relates group_id to user_id.
Create Table Group_user
(group_id,
user_id primary key is (gorup_id, user_id))
Then do a three way join when you want all the data together. This is the basic way you model a many-to-many relationship.
Upvotes: 0
Reputation: 225164
I would recommend creating one table to hold all posts for all blogs, then have a table to store all the blogs' information, then a table to store all the blogs' posts, referenced by ID. Then you just add, for example:
Into posts: ID=(auto increment value), Title='The title', Content='The content'
Into blog posts: blogID=(the ID of blog #1 to insert the post into), postID=(the auto increment value from last time)
Into blog posts: blogID=(the ID of blog #2 to insert the post into), postID=(the auto increment value from last time)
That way, the post is linked in so when it is edited or removed changes are reflected on all blogs, and you can also get a quick list of all blogs a post is in using something like SELECT * FROM blogPosts WHERE postID=id_of_post
.
Upvotes: 0