- Intro to Fast Rails Development
- Rails Quick Start
- Rails Scaffold
- Scaffold Tour I - Resources
- Scaffold II - Forms
- User Post Relationship
- Validations & Filters
- Correct User
- Adjusting the Pages
- Header Adjustments
- Simple Twist
- 1000 Words
- Live Site on Heroku
Build a quick blog platform with Rails. (Beta tutorial.)
User Post Relationship
User and Posts
Currently, Posts don't belong to anyone. Anyone who visits the site can edit or delete any posts, even without signing in! As a first step, let's add associate each Post with a user. This is similar to associating each Product with a Category in the automated store. Can you create the migration to mark each Post with a User?
Each post will belong to one User, so each post should have a user_id
to identify the User:
rails generate migration AddUserIdToPosts user_id:integer
Before running the migration, let's make one edit to the migration file. To quickly find posts for a specific user, add an index to the user_id column to make lookups much faster. Open up the migration file you just generated and add one more line:
[timestamp]_add_user_id_to_posts.rb
class AddUserIdToPosts < ActiveRecord::Migration
def change
add_column :posts, :user_id, :integer
add_index :posts, :user_id #adds index
end
end
Now you can run:
rake db:migrate
...which will add the user_id column and index to the Posts table.
Next, can you add the association to the User and Post models so they're correctly associated with each other?
Add the following line to your post model:
belongs_to :user
Add the following line to your User model:
has_many :posts
Editing the Controller
Now let's modify post_controller's create action so it associates each post with a user.
Q: How do we know who the user is, should we pass in a user ID from the form?
A: No, that would be terrible security practice! Malicious users could pass in user_id's of other users to create posts for them. That's why we used strong params, so the user_id can't be modified in that manner. Instead, we'll use Devise's current_user
method, which return the current signed in user.
Can you set the user in the create action?
Just add one line to set the user:
def create
@post = Post.new(post_params)
@post.user = current_user
#remaining code...
end
Trying it Out
You've only added a few lines of code, but you can now associate every Post with a User. Try it out by creating a couple of posts, and then use the console to get your user's posts.
user = Post.last.user
user.posts
Q: What happens if you create a post when not signed in?
A: Currently, the site allows that, so let's go ahead and fix that next.