Reputation: 2500
In my Sinatra view, I have a table which will display all records from my database. When I click to delete a record I will call the jquery ajax to send the delete request. My route will then handle the request, delete the record in the database and redirect the app to its homepage.
The problem is that the view doesn't refresh after delete and still show some old data. When I close the browser and open it again the data still exists in the view even though the delete request has returned 200 code status.
# 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
And here is the simplified code of the view:
# index.erb
<% if [email protected]? %>
<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 %>
Here is the full source code on GitHub: https://github.com/huyvohcmc/bitly
Upvotes: 1
Views: 431
Reputation: 12251
There is reloading a page and there is redirecting to a page.
When you use the redirect
method of Sinatra it responds with a 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
By calling redirect "/"
you are asking the browser to redirect to "/", which would normally trigger a fresh page. However, you're already on that page, so the jQuery code is receiving a redirect and you're asking for a reload via location.reload()
upon success. Success is generally indicated by responding with a 2xx code, so I'd posit that the redirect means the success handler isn't firing, and because the browser realises you're already on the page the redirect has asked for it doesn't attempt a redirect either and you end up with no fresh data.
The route should probably look more like this:
delete '/delete/:record_id' do
id = get_record_id
delete_record id
halt 200 # think about handling errors too
end
The success handler should now fire. Moral of the story, be explicit in what you want to do, don't rely on side effects (like a redirect sharing some properties of a reload) to do what you want.
Upvotes: 1
Reputation: 2500
Well after some hours googling I can finally make it to work by changing both the controller and the view a little bit:
# 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();
}
})
}
Basically, I have to reload the page manually after deleting a record. I don't know yet if Sinatra support this functionality but for now this method works like a charm :)
Upvotes: 1