My Rails 5 app makes four API calls and displays the results on the show page. I have button_to in place that calls an Ajax POST request on the show page so users can vote on their favorite. This triggers some JS, which works fine in dev and production on my laptop. Browsers on my iphone, though, use the full controller URI and try to download it. The button_to returns a 204: no content status.
I've tried redirecting to another /show page after the Ajax call as well as redirecting with the gem browser if the user is on mobile, but those pages crash if the user refreshes them. I've tried explicitly returning a 200 status in the controller, but that wants a redirect. I want the user to stay on the /show page, so nothing else with redirecting works for me.
In the model:
def self.first_api(term)
call_url = FIRST_CALL_URL
response = HTTParty.get(call_url,
{ headers: {
"Accept": "application/json",
"app_id": "#{ENV['FIRST_API_APP_ID']}",
"app_key": "#{ENV['FIRST_API_APP_KEY']}" }
})
if response.include?("!DOCTYPE")
"NO DEFINITION"
else
response
end
end
Controller (truncated):
def show
@full_call = FullCall.find(params[:id])
end
def create
@full_call = FullCall.where(word:full_call_params[:word]).first_or_create do |call|
call.first_api_response = FirstCall.first_api(call.word)
end
end
if @full_call.save
redirect_to @full_call
else
render 'new'
end
def vote_for_first
@full_call.first_vote += 1
@full_call.save
end
private
def full_call_params
params.require(:full_call).permit(:word, :definition)
end
Relevant routes:
resources :full_calls
post 'vote_for_first', to: 'full_calls#vote_for_first'
/show page:
<p>
<div>
<h2 id='full-call-heading'><%= @full_call.word.upcase %></h2>
<div id='full-call-alert'></div>
</div>
</p>
<div class="container">
<div class="card-title">
<div class="card card-default">
<div class="card-header"><strong>First Call Definition:</strong>
<div>
<%= button_to('VOTE FOR FIRST', { controller: 'full_calls',
action: 'vote_for_first',
id: @full_call,
remote: true },
{ class: "btn btn-outline-secondary btn-sm vote-btn" }) %>
</div>
</div>
<div class="card-block"><%= @full_call.first_api_response %></div>
application.js
$(document).on('turbolinks:load', function() {
$('.vote-btn').on('click', function() {
setTimeout(function() {
$('.vote-btn').attr('disabled', true);
$('#full-call-alert').append("<h5>Thanks for voting!</h5>").hide().slideDown('slow');
}, 100);
});
});
And, finally, the URL that returns the "Download failed" message only on mobile browsers:
myapp.herokuapp.com/vote_for_first?id=12&remote=true
Any ideas?