首页 > 解决方案 > Rails 新的初始化对象创建一个空记录

问题描述

我有两个模型叫做TodoListand TodoItem。在 TodoItem 索引页面中,我正在显示新表单和待办事项列表。一切正常但它在浏览器中生成一个空记录。

class TodoItem < ApplicationRecord
  belongs_to :todo_list
end
class TodoList < ApplicationRecord
  has_many :todo_items, dependent: :destroy
end

控制器有:

class TodoItemsController < ApplicationController

  def index
    @todo_list = TodoList.find(params[:todo_list_id])
    @todo_items = @todo_list.todo_items
    @new_todo = @todo_list.todo_items.new
  end

  def create
    @todo_list = TodoList.find(params[:todo_list_id])
    @todo_item = @todo_list.todo_items.new(params.require(:todo_item).permit(:description, :complete_at))
    if @todo_item.save
      redirect_to todo_list_todo_items_path(@todo_list)
    end
  end
end

index.html.erb

<div>
  
  <div>
    <% form_with(model: [@todo_list, @todo_item], local: true) do |f| %>
      <% f.text_field :description %>
      <% f.submit %>
    <% end %>
  </div>
    <ul>
    <% @todo_items.each do |todo_item| %>
      <li><%= todo_item.description %></li>
    <% end %>
    </ul>
</div>

标签: ruby-on-rails

解决方案


class TodoItemsController < ApplicationController
  # use callbacks instead of repeating yourself
  before_action :set_todolist, only: [:new, :create, :index]

  def index
    @todo_items = @todo_list.todo_items
    @todo_item = TodoItem.new
  end

  def create
    @todo_item = @todo_list.todo_items.new(todo_list_params)
    if @todo_item.save
      redirect_to [@todo_list, :todo_items]
    else
      render :new
    end
  end

  private

  def set_todolist
    @todo_list = TodoList.find(params[:todo_list_id])
  end

  # use a private method for your params whitelist for readibility
  # it also lets you reuse it for the update action
  def todo_list_params
    params.require(:todo_item)
          .permit(:description, :complete_at)
  end
end

您在索引操作中设置不同的实例变量 ( @new_todo)。[@todo_list, @todo_item]多态路由助手从数组上的调用中查找路由助手。因此,如果@todo_item是 nil,它会改为调用todo_lists_path- 哎呀!

您还需要考虑如何响应无效数据。通常在 Rails 中,这意味着渲染新视图。如果您在另一个视图(例如索引视图)中呈现表单,则重新呈现相同的视图可能会有些棘手,因为您必须将所有相同的数据设置为导致重复的操作。


推荐阅读