You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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:

1. Create a Todo Model with Polymorphic Associations

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 owner
  • item_type + item_id: Polymorphic fields to connect to either an Article or Announcement
  • completed: A boolean to track if the todo is done (defaults to false)

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.

3. Add Functionality to Add Followed Items to Todos

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" %>
4. Build the Todo List View

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 %>
5. Quick Notes for New Developers
  • Authentication: Make sure you're using a gem like Devise for user authentication (it handles the current_user and authenticate_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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:33:25