一些删除请求后,Sinatra视图不会刷新

时间:2018-01-11 20:06:11

标签: jquery ruby ajax sinatra rack

在我的Sinatra视图中,我有一个表格,它将显示我数据库中的所有记录。当我单击删除记录时,我将调用jquery ajax发送删除请求。然后我的路线将处理请求,删除数据库中的记录并将应用程序重定向到其主页。

问题是删除后视图没有刷新,仍显示一些旧数据。当我关闭浏览器并再次打开它时,即使删除请求已返回200代码状态,数据仍然存在于视图中。

# application_controller.rb

require 'sinatra'
require 'sinatra/reloader'
require './application_helper' if development?

enable :logging

helpers ApplicationHelper

...

delete '/delete/:record_id' do
  id = get_record_id
  delete_record id
  redirect '/'
end

get '/' do
  @links = get_all @user_ip
  erb :index, { :layout => :layout }
end

以下是视图的简化代码:

# index.erb

<% if !@links.empty? %>
<div class="table-responsive" style="margin-top: 30px">
  <table class="table table-striped table-hover" style="width: 600px">
    <thead>
      <tr>
        <th>Original URL</th>
        <th>Short URL</th>
        <th>Delete</th>
      </tr>
    </thead>
    <tbody>
      <% @links.each do |record| %>
        <tr>
          <td><a href=<%= record.long_url %>><%= record.long_url %></td>
          <td><a href=<%= record.id %>><%= record.short_url %></td>
          <td>
            <button class="btn btn-default" onClick="deleteRecord(<%= record.id %>)">
              <span class="glyphicon glyphicon-trash" style="color: red"></span>
            </button>
          </td>
        </tr>
      <% end %>
    </tbody>
  </table>
</div>
<% end %>

以下是GitHub上的完整源代码:https://github.com/huyvohcmc/bitly

2 个答案:

答案 0 :(得分:1)

重新加载页面,重定向到页面。

当您使用Sinatra的redirect方法时,它会以302 or 303 status code回复。

# @see https://github.com/sinatra/sinatra/blob/v2.0.0/lib/sinatra/base.rb#L271
# Halt processing and redirect to the URI provided.
def redirect(uri, *args)
  if env['HTTP_VERSION'] == 'HTTP/1.1' and env["REQUEST_METHOD"] != 'GET'
    status 303
  else
    status 302
  end

  # According to RFC 2616 section 14.30, "the field value consists of a
  # single absolute URI"
  response['Location'] = uri(uri.to_s, settings.absolute_redirects?, settings.prefixed_redirects?)
  halt(*args)
end

通过调用redirect "/",您要求浏览器重定向到“/”,这通常会触发新页面。但是,您已经在该页面上,因此jQuery代码正在接收重定向,您要求在成功时通过location.reload()重新加载。成功通常通过响应2xx代码来表示,所以我认为重定向意味着成功处理程序没有触发,并且因为浏览器意识到你已经在页面上,重定向已经要求它不会尝试重定向,你最终没有新的数据。

路线应该看起来更像这样:

delete '/delete/:record_id' do
  id = get_record_id
  delete_record id
  halt 200 # think about handling errors too
end

成功处理程序现在应该触发。故事的道德,明确你想做什么,不要依赖副作用(比如重定向共享一些重载的属性)来做你想做的事。

答案 1 :(得分:0)

经过几个小时的谷歌搜索后,我终于可以通过更改控制器和视图来实现它的工作:

# application_controller.rb

delete '/delete/:record_id' do
  id = get_record_id
  delete_record id
  redirect '/'
end

# index.erb

var deleteRecord = function (id) {
    $.ajax({
      url: '/delete/' + id,
      type: 'DELETE',
      success: function(data) {
        location.reload();
      }
    })
  }

基本上,我必须在删除记录后手动重新加载页面。我不知道Sinatra是否支持此功能,但现在这种方法就像魅力一样:)