Rails 4.2.5 + Ruby 2.3.3新手求助:实现用户专属待办清单功能
Hey there! Since you're new to programming and working with Rails 4.2.5 + Ruby 2.3.3, let's break this down step by step to build your to-do list system that integrates followed articles and announcements. Here's a straightforward, beginner-friendly approach:
First, we'll make a Todo model that can link to either an Article or Announcement (this is called a polymorphic association, which avoids duplicating code for similar associations). Run this generator command in your terminal:
rails generate model Todo user:references item:references{polymorphic} completed:boolean rake db:migrate
This creates a table with:
user_id: Links the todo to its owneritem_type+item_id: Polymorphic fields to connect to either an Article or Announcementcompleted: A boolean to track if the todo is done (defaults tofalse)
Update the Todo model to define the associations:
# app/models/todo.rb class Todo < ActiveRecord::Base belongs_to :user belongs_to :item, polymorphic: true # Default to showing only incomplete todos default_scope -> { where(completed: false) } end
Add associations to your User, Article, and Announcement models:
# app/models/user.rb class User < ActiveRecord::Base # Your existing associations has_many :articles has_many :announcements acts_as_follower # New todo association (delete todos if user is removed) has_many :todos, dependent: :destroy end
# app/models/article.rb class Article < ActiveRecord::Base belongs_to :user acts_as_followable # Link to todo (one todo per article per user) has_one :todo, as: :item, dependent: :destroy end
Repeat the same has_one :todo, as: :item, dependent: :destroy line for your Announcement model.
Let's add a way for users to manually add followed articles/announcements to their todo list (we'll use a button on the item's show page).
First, add routes for the "add to todo" action and todo management:
# config/routes.rb resources :articles do member do post 'add_to_todo' end end resources :announcements do member do post 'add_to_todo' end end # Routes for viewing/updating/deleting todos resources :todos, only: [:index, :destroy, :update]
Next, add the add_to_todo action to your ArticlesController (repeat for AnnouncementsController):
# app/controllers/articles_controller.rb def add_to_todo @article = Article.find(params[:id]) # Check if the user already added this article to their todos if current_user.todos.where(item: @article).exists? flash[:notice] = "This article is already in your todo list!" else current_user.todos.create(item: @article) flash[:success] = "Added to your todo list!" end redirect_to @article end
Add a "Add to Todo" button to your article show view (copy this for your announcement show view too):
<!-- app/views/articles/show.html.erb --> <%= button_to "Add to Todo List", add_to_todo_article_path(@article), method: :post, class: "btn btn-primary" %>
Create a page where users can see, complete, and delete their todos:
First, set up the TodosController:
# app/controllers/todos_controller.rb class TodosController < ApplicationController # Make sure only logged-in users can access their todos before_action :authenticate_user! before_action :set_todo, only: [:destroy, :update] def index # Show the current user's todos, newest first @todos = current_user.todos.order(created_at: :desc) end def destroy @todo.destroy flash[:success] = "Removed from your todo list!" redirect_to todos_path end def update if @todo.update(todo_params) flash[:success] = "Todo marked as completed!" else flash[:error] = "Failed to update todo!" end redirect_to todos_path end private # Ensure users can only modify their own todos def set_todo @todo = current_user.todos.find(params[:id]) end def todo_params params.require(:todo).permit(:completed) end end
Then create the index view for todos:
<!-- app/views/todos/index.html.erb --> <h1>My Todo List</h1> <ul class="todo-list"> <% @todos.each do |todo| %> <li> <% if todo.item_type == "Article" %> <strong>Article:</strong> <%= link_to todo.item.title, todo.item %> <% elsif todo.item_type == "Announcement" %> <strong>Announcement:</strong> <%= link_to todo.item.title, todo.item %> <% end %> <%= button_to "Mark as Completed", todo_path(todo), method: :patch, params: { todo: { completed: true } }, class: "btn btn-sm btn-success" %> <%= button_to "Remove", todo_path(todo), method: :delete, class: "btn btn-sm btn-danger" %> </li> <% end %> </ul> <% if @todos.empty? %> <p>Your todo list is empty! Add some followed articles or announcements to get started.</p> <% end %>
- Authentication: Make sure you're using a gem like Devise for user authentication (it handles the
current_userandauthenticate_user!methods we used). - Testing: As a beginner, start with manual testing—log in, follow an article, add it to your todo list, and check if it shows up!
- Customization: You can tweak the views to match your app's design, or add features like sorting todos by date.
内容的提问来源于stack exchange,提问作者Joao Quaresma

