Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
281 views
in Technique[技术] by (71.8m points)

Rails new initialized object create an empty record

I have two model called TodoList and TodoItem. In the TodoItem index page, i'm showing new form and list of todo items. Everything works perfect But it generate an empty record while in browser.

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

controllers have:

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>
question from:https://stackoverflow.com/questions/65949145/rails-new-initialized-object-create-an-empty-record

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
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

You where setting a different instance variable (@new_todo) in you index action. The polymorphic route helpers that look up the route helpers from [@todo_list, @todo_item] call compact on the array. So if @todo_item is nil its going to call todo_lists_path instead - ooops!

You alway also need to consider how you are going to respond to invalid data. Usually in Rails this means rendering the new view. If you are rendering the form in another view such as the index view it can get kind of tricky to re-render the same view as you have to set up all the same data as that action which leads to duplication.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...