In the world of web development, one of the most powerful features of Rails is its seamless ability to manage user authentication through Devise. But what happens when you want to extend this functionality to allow users to create and manage their own resources, like posts? Let’s dive into how you can associate Devise users with posts in your Rails application to build richer, more interactive experiences.
Do you need more hands for your Ruby on Rails project?
Step 1: Setting Up Your Models
To begin, we’ll create a Post model that includes a user_id field to link it to a specific user. This is achieved using Rails’ built-in references feature:
rails generate model Post title:string content:text user:references rails db:migrate
This creates a user_id column in the posts table and establishes the groundwork for associating posts with users.
Next, define the relationships in the models:
User Model
class User < ApplicationRecord devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable # Association with posts has_many :posts, dependent: :destroy end
Post Model
class Post < ApplicationRecord belongs_to :user # Optional validations validates :title, :content, presence: true end
Step 2: Configuring the Controller
Now, let’s set up a PostsController to manage post creation. Ensure that only authenticated users can create posts by using Devise’s authenticate_user! method.
Generate the Controller
rails generate controller Posts
Customize the Controller
Update the PostsController with the following logic:
class PostsController < ApplicationController before_action :authenticate_user! def new @post = Post.new end def create @post = current_user.posts.build(post_params) # Associate the post with the current user if @post.save redirect_to @post, notice: 'Post was successfully created.' else render :new end end def index @posts = Post.all end def show @post = Post.find(params[:id]) end private def post_params params.require(:post).permit(:title, :content) end end
The key line here is:
@post = current_user.posts.build(post_params)
This ensures that the post being created is automatically associated with the logged-in user.
Step 3: Updating Routes
In config/routes.rb, add routes for posts:
Rails.application.routes.draw do devise_for :users resources :posts root to: 'posts#index' # Set a default root route end
Step 4: Building the Views
New Post Form
Create a form to allow users to submit posts in app/views/posts/new.html.erb:
<%= form_with model: @post, local: true do |form| %> <% if @post.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2> <ul> <% @post.errors.full_messages.each do |message| %> <li><%= message %></li> <% end %> </ul> </div> <% end %> <div> <%= form.label :title %><br> <%= form.text_field :title %> </div> <div> <%= form.label :content %><br> <%= form.text_area :content %> </div> <div> <%= form.submit 'Create Post' %> </div> <% end %>
Step 5: Testing the Association
To test this functionality:
- Start the Rails server: rails server
- Sign up a user at /users/sign_up.
- Navigate to /posts/new to create a post.
- Check that the post is saved with the user_id matching the logged-in user.
Step 6: Displaying User-Specific Posts
If you’d like to show posts created only by the logged-in user, update the index action:
def index @posts = current_user.posts end
This restricts the displayed posts to those created by the authenticated user.
Conclusion
By associating Devise users with posts, you’ve unlocked a powerful feature for your Rails application. This foundation can be extended to more complex models and relationships, enabling users to interact with your app in meaningful ways. Whether you’re building a blog, a forum, or a social media platform, this pattern sets you on the path to success.
Happy coding! 🚀
Top comments (0)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.