Every time I hit submit in my rails app it sends the request 2x. I can get rid of the second partial by hitting refresh. This is a nested app. Todo has_many Items. I included the controllers and the create and the partials. I included a photo to make a bit more clear.
每次我在我的rails应用程序中点击提交时,它都会发送请求2次。我可以通过点击刷新摆脱第二部分。这是一个嵌套的应用程序。 Todo has_many项目。我包括控制器和创建和部分。我添加了一张照片以使其更加清晰。
create.js.erb
$('.todo-items').prepend("<%= escape_javascript(render(@item)) %>");
Items Controller:
class ItemsController < ApplicationController
before_action :set_item, only: [:show, :edit, :update, :destroy]
before_action :set_todo
respond_to :html, :js
# GET /items
# GET /items.json
def index
@items = Item.all
end
# GET /items/1
# GET /items/1.json
def show
@item = Item.find(params[:id])
end
# GET /items/new
def new
@item = @todo.items.build
end
# GET /items/1/edit
def edit
@item = Items.find(params[:id])
end
# POST /items
# POST /items.json
def create
@item = @todo.items.build(item_params)
respond_with(@item) do |format|
if @item.save
format.html { redirect_to [@todo], notice: 'Item was successfully created.' }
format.json { render :show, status: :created, location: @item }
else
format.html { render :new }
format.json { render json: @item.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /items/1
# PATCH/PUT /items/1.json
def update
@item = Item.find(params[:id])
respond_to do |format|
if @item.update(item_params)
format.html { redirect_to [@todo, @item], notice: 'Item was successfully updated.' }
format.json { render :show, status: :ok, location: @item }
else
format.html { render :edit }
format.json { render json: @item.errors, status: :unprocessable_entity }
end
end
end
# DELETE /items/1
# DELETE /items/1.json
def destroy
@item = Item.find(params[:id])
@item.destroy
respond_to do |format|
format.html { redirect_to items_path }
format.json { head :no_content }
format.js { render layout: false }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_item
@item = Item.find(params[:id])
end
def set_todo
@todo = Todo.find(params[:todo_id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def item_params
params.require(:item).permit(:content, :todo_id)
end
end
Todos Controller
class TodosController < ApplicationController
respond_to :html, :js
before_action :set_todo, only: [:show, :edit, :update, :destroy]
# GET /todos
# GET /todos.json
def index
@todos = Todo.all
@todo = Todo.new
end
# GET /todos/1
# GET /todos/1.json
def show
@todo= Todo.find(params[:id])
end
# GET /todos/new
def new
@todo = Todo.new
#3.times{@todo.items.build}
end
# GET /todos/1/edit
def edit
end
# POST /todos
# POST /todos.json
def create
@todo = Todo.new(todo_params)
#@todo.items.build
respond_to do |format|
if @todo.save
format.html { redirect_to todo_path, notice: 'Todo was successfully created.' }
format.json { render :show, status: :created, location: @todo }
else
format.html { render :new }
format.json { render json: @todo.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /todos/1
# PATCH/PUT /todos/1.json
def update
@todo = Todo.find(params[:id])
respond_to do |format|
if @todo.update(todo_params)
format.html { redirect_to todos_url, notice: 'Todo was successfully updated.' }
format.json { render :show, status: :ok, location: @todo }
else
format.html { render :edit }
format.json { render json: @todo.errors, status: :unprocessable_entity }
end
end
end
# DELETE /todos/1
# DELETE /todos/1.json
def destroy
@todo.destroy
@todo.items.destroy
respond_to do |format|
format.html { redirect_to todos_url, notice: 'Todo was successfully destroyed.' }
format.json { head :no_content }
end
end
def todo_completed
@todo = Todo.find(params[:id])
@todo.completed = true
if @todo.save
flash[:notice] = "Task was completed."
else
flash[:error] = "There was an error completing the task."
end
#redirect_to tasks_path
respond_with(@todo) do |f|
f.html { redirect_to todos_path }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_todo
@todo = Todo.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def todo_params
params.require(:todo).permit(:title, :completed, items_attributes: [:content,:completed, :_destroy])
end
end
This is the show page the one in the photo for Todo. It is rendering the items underneath that specific todo.
这是Todo照片中的展示页面。它正在渲染特定待办事项下面的项目。
<p>Here are all the things you need to complete</p>
<div class="todo-items">
<%= render partial: 'items/item' %>
</div>
<br>
<div class='new-item'>
<%= render 'items/form'%>
</div>
<%= link_to 'Back', todos_path %>
Items/item
<p>todo/show this is the partial <%= @todo.title %></p>
<table class='table table-bordered'>
<thead>
<tr>
<th>Description</th>
<th> Time Left </th>
<th> Mark Complete </th>
</tr>
</thead>
<tbody>
<% @todo.items.each do |item| %>
<tr>
<td><%= link_to item.content, [@todo, item] %></td>
<td><%= item.days_left %>
<td>
<%= link_to todo_item_path(@todo,item), method: :delete, data: { confirm: 'Are you sure?' }, remote: true, class: 'delete_item' do %>
<i class="fa fa-check"></i>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
<br>
<p>end of partial item</p>
Item/form
<p>
<strong>Todo:</strong>
<%= @todo.title %>
</p>
<%= form_for [@todo, @todo.items.build], remote: true do |f| %>
<div class="field">
<%= f.label :content %><br>
<%= f.text_field :content %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
A little more info from the console. It starts when I click on the list(Groceries) and end with me hitting submit to add the item
从控制台获得更多信息。当我点击列表(Groceries)并以我点击提交添加项目结束时开始
Started GET "/todos/25" for 127.0.0.1 at 2014-10-08 19:19:58 -0500
Processing by TodosController#show as HTML
Parameters: {"id"=>"25"}
Todo Load (0.3ms) SELECT "todos".* FROM "todos" WHERE "todos"."id" = ? LIMIT 1 [["id", 25]]
CACHE (0.0ms) SELECT "todos".* FROM "todos" WHERE "todos"."id" = ? LIMIT 1 [["id", "25"]]
Item Load (0.4ms) SELECT "items".* FROM "items" WHERE "items"."todo_id" = ? [["todo_id", 25]]
Rendered items/_item.html.erb (42.9ms)
Rendered items/_form.html.erb (17.3ms)
Rendered todos/show.html.erb within layouts/application (66.6ms)
Completed 200 OK in 346ms (Views: 339.5ms | ActiveRecord: 1.3ms)
Started POST "/todos/25/items" for 127.0.0.1 at 2014-10-08 19:20:12 -0500
Processing by ItemsController#create as JS
Parameters: {"utf8"=>"✓", "item"=>{"content"=>"Cereal"}, "commit"=>"Create Item", "todo_id"=>"25"}
Todo Load (0.2ms) SELECT "todos".* FROM "todos" WHERE "todos"."id" = ? LIMIT 1 [["id", 25]]
(0.3ms) begin transaction
Todo Load (0.2ms) SELECT "todos".* FROM "todos" WHERE "todos"."id" = ? LIMIT 1 [["id", 25]]
SQL (0.5ms) INSERT INTO "items" ("content", "created_at", "todo_id", "updated_at") VALUES (?, ?, ?, ?) [["content", "Cereal"], ["created_at", "2014-10-09 00:20:12.060569"], ["todo_id", 25], ["updated_at", "2014-10-09 00:20:12.060569"]]
(148.1ms) commit transaction
Item Load (0.2ms) SELECT "items".* FROM "items" WHERE "items"."todo_id" = ? [["todo_id", 25]]
Rendered items/_item.html.erb (9.8ms)
Rendered items/create.js.erb (12.5ms)
Completed 200 OK in 180ms (Views: 15.2ms | ActiveRecord: 149.4ms)
1 个解决方案
#1
0
The problem is with your create.js.erb file. You have below code:
问题出在您的create.js.erb文件中。你有下面的代码:
$('.todo-items').prepend("<%= escape_javascript(render(@item)) %>");
In this code you are pre-pending html in todo-items
you should replace items each time instead. like below :
在此代码中,您是todo-items中的预先挂起的html,您应该每次替换项目。如下:
$('.todo-items').html("<%= escape_javascript(render(@item)) %>");
This will replace html each time with new html.
这将每次用新的html替换html。
#1
0
The problem is with your create.js.erb file. You have below code:
问题出在您的create.js.erb文件中。你有下面的代码:
$('.todo-items').prepend("<%= escape_javascript(render(@item)) %>");
In this code you are pre-pending html in todo-items
you should replace items each time instead. like below :
在此代码中,您是todo-items中的预先挂起的html,您应该每次替换项目。如下:
$('.todo-items').html("<%= escape_javascript(render(@item)) %>");
This will replace html each time with new html.
这将每次用新的html替换html。