I'm getting a "406 Not Acceptable in 13ms (ActiveRecord: 0.6ms)" error when I tried to implement ajax. Code works in normal html without any respond_to blocks. I've narrowed down the issue to the respond_to blocks and I'm stumped now. None of the other solutions on SO & google of the same error seem to apply or work.
What causes a 406 error when using the respond_to block whether html only or ajax/js included?
How to fix the 406 error?
Is it ok to use redirect_to in the respond_to block for format.html as shown in code below?
Let me know if you need more info.
View (haml):
Normal html code
%div.control-group.controls
= button_to "Delete Gcal User", #gcal_user, method: :delete, class: "btn btn-danger"
AJAX code
%div.control-group.controls
= button_to "Delete Gcal User", #gcal_user, method: :delete, remote: true, class: "btn btn-danger"
JS code (coffeescript) for AJAX
$('#calendar').empty();
Controller:
class GcalUsersController < ApplicationController
def destroy
#gcal_user = current_user.gcal_user
# if #gcal_user.delete
# flash[:notice] = "#{#gcal_user.username} deleted"
# end
# redirect_to user_root_path # <-- using this in html mode, app works i.e. no 406 error
respond_to do |format|
format.html { redirect_to(user_root_path) } # <-- using this in html mode instead of above line, app fails i.e. 406 error
# format.js # <-- using this in ajax mode, app fails i.e. 406 error
end
end
end
You want to respond with "json", not with "js" (which means JavaScript here). jquery_ujs, the gem that adds the functionality for method: :delete, expects JSON.
def destroy
#gcal_user = current_user.gcal_user
#gcal_user.delete
respond_to do |format|
format.html { redirect_to user_root_path }
format.json { head :no_content }
end
end
The problem was caused by routes. Using the singular resource :gcal_user instead of the plural resources :gcal_users caused the URL to be formated differently. The singular resource uses the "/gcal_user.[id]" which caused the respond_to block to think the format must be in ".[id]" instead of the ".js" or ".html".
See Respond_to does not redirect, gives 406 Not Acceptable error
Related
In my rails app I have a ajax request to the server, to store some data. This used to work without any problem, but now I get an error:
ActionController::UnknownFormat (ActionController::UnknownFormat):
app/controllers/reservations_controller.rb:45:in `create'
As following is the controller and my javascript file where I declare the datatype do be JSON
class ReservationController < ApplicationController
respond_to :html, :json
def create
...
respond_to do |format|
if #reservation.save
format.html do
redirect_to '/'
end
format.json { render json: #reservation.to_json }
else
render 'new'
end
end # respond_to
end # create
end # ReservationController
function.js
$.ajax({
url: url_link,
dataType: 'json',
type: 'POST',
data: dataToSend
})
The complete error log is:
Completed 406 Not Acceptable in 45ms
ActionController::UnknownFormat (ActionController::UnknownFormat):
app/controllers/bookings_controller.rb:45:in `create'
Rendered /Users/tiagovieira/.rvm/gems/ruby-2.0.0-p451/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/_source.erb (0.5ms)
Rendered /Users/tiagovieira/.rvm/gems/ruby-2.0.0-p451/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/_trace.erb (0.8ms)
Rendered /Users/tiagovieira/.rvm/gems/ruby-2.0.0-p451/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (0.8ms)
Rendered /Users/tiagovieira/.rvm/gems/ruby-2.0.0-p451/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (9.6ms)
Update the create action as below:
def create
...
respond_to do |format|
if #reservation.save
format.html do
redirect_to '/'
end
format.json { render json: #reservation.to_json }
else
format.html { render 'new'} ## Specify the format in which you are rendering "new" page
format.json { render json: #reservation.errors } ## You might want to specify a json format as well
end
end
end
You are using respond_to method but anot specifying the format in which a new page is rendered. Hence, the error ActionController::UnknownFormat .
You can also modify your config/routes.rb file like:
get 'ajax/:action', to: 'ajax#:action', :defaults => { :format => 'json' }
Which will default the format to json.
It is working fine for me in Rails 4.
Or if you want to go even further and you are using namespaces, you can cut down the duplicates:
namespace :api, defaults: {format: 'json'} do
#your controller routes here ...
end
with the above everything under /api will be formatted as json by default.
There is another scenario where this issue reproduces (as in my case). When THE CLIENT REQUEST doesn't contain the right extension on the url, the controller can't identify the desired result format.
For example: the controller is set to respond_to :json (as a single option, without a HTML response)- while the client call is set to /reservations instead of /reservations.json.
Bottom line, change the client call to /reservations.json.
This problem happened with me and sovled by just add
respond_to :html, :json
to ApplicationController file
You can Check Devise issues on Github: https://github.com/plataformatec/devise/issues/2667
Well I fond this post because I got a similar error.
So I added the top line like in your controller
respond_to :html, :json
then I got a different error(see below)
The controller-level respond_to' feature has been extracted to theresponders` gem. Add it to your Gemfile to continue using this feature: gem 'responders', '~> 2.0' Consult the Rails upgrade guide for details.
But that had nothing to do with it.
I got this error when trying to render an XML response - I had to change my template name from index.html.erb to index.xml.erb and then it worked.
mine was fixed because i didnt have / / in the scope,
i had this (getting error for json):
Rails.application.routes.draw do
scope '(:base_url)', base_url: #{ENV.fetch('BASE_URL').to_s} do
...
end
end
instead of this (fixed):
Rails.application.routes.draw do
scope '(:base_url)', base_url: /#{ENV.fetch('BASE_URL').to_s}/ do
...
end
end
I'm playing about with the Ruby Feedzirra gem and have managed to acheive what I set out to do by using it in the controller.
Though everything I've seen has mentioned using it in the model. I was just wondering if this is ok to do in the controller, if not, how might I go about achieving the same in the model?
I want to submit a Feed URL and use that to update my model with the rest of the information about the feed.
Feeds_controller.rb
def create
#feed = Feed.new(params[:feed])
feed = Feedzirra::Feed.fetch_and_parse(#feed.feed_url)
#feed.title = feed.title
#feed.url = feed.url
#feed.last_modified = feed.last_modified
respond_to do |format|
if #feed.save
format.html { redirect_to #feed, notice: 'Feed was successfully created.' }
format.json { render json: #feed, status: :created, location: #feed }
else
format.html { render action: "new" }
format.json { render json: #feed.errors, status: :unprocessable_entity }
end
end
end
feed.rb
class Feed < ActiveRecord::Base
attr_accessible :feed_url, :last_modified, :title, :url
end
I'd make an instance method on the Model and use that in the controller so
class Feed < ActiveRecord::Base
def fetch!
feed = Feedzirra::Feed.fetch_and_parse(feed_url) # probably want some eror handling here
title = feed.title
url = feed.url
last_modified = feed.last_modified
self #or nil if you like
end
end
then your controller thins down to
def create
#feed = Feed.new(params[:feed])
#feed.fetch!
respond_to do |format|
if #feed.save
format.html { redirect_to #feed, notice: 'Feed was successfully created.' }
format.json { render json: #feed, status: :created, location: #feed }
else
format.html { render action: "new" }
format.json { render json: #feed.errors, status: :unprocessable_entity }
end
end
end
The cool thing here is that if this gets too slow you can use something like Resque to run this in the background and just return a "your request is being processed" message to the user, then alert them asynchronously when the the request is done (might not work so well for the json request)
You really don't want to use something like a RSS parser in your controller. That will slow the responsiveness of that URL and your server.
Instead, run the RSS parser in a separate application, or at least a separate thread, and store the retrieved feeds in a database table for rapid access.
I have a delete link that makes a remote call:
<%= link_to image_tag("trash.png"), [current_user, bookcase], method: :delete, :remote => true, confirm: "You sure?", title: bookcase.image %>
In my controller, I end the delete function with a redirect:
def destroy
#bookcase.destroy
redirect_to current_user
end
This works, except it's redirecting the user to the 'user/show.html.erb' file instead of the 'user/show.js.erb' file. How can I redirect the user, specifying which format to use?
Don't know if this is answering this specific question, but some might find the following helpful:
module AjaxHelper
def ajax_redirect_to(redirect_uri)
{ js: "window.location.replace('#{redirect_uri}');" }
end
end
class SomeController < ApplicationController
include AjaxHelper
def some_action
respond_to do |format|
format.js { render ajax_redirect_to(some_path) }
end
end
end
I'm pretty sure you can specify the format in the redirect_to like this
redirect_to current_user, format: 'js'
I am pretty sure this code will work.
render :js => "window.location = '/jobs/index'
You can use this code in action /controller_name/action name/
I tried the accepted answer but didn't work for me (RAILS 6), what worked for me is this :
format.js { redirect_to current_user }
Hope this help someone
I'm getting a 500 error when I try to use ajax to delete a post. It works just fine without using ajax.
In the view I have this to delete a post
<%= link_to 'Destroy', post, confirm: 'Are you sure?', method: :delete,:remote => true, :class => 'delete_post' %>
In the controller I have this for the Destroy method.
def destroy
#post = Post.find(params[:id])
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url }
format.js
end
end
In the browser I get a 500 error.
Run Rails 3.1 Ruby 1.9.2-p290 and brand new 3.1 app
What am I doing wrong
It's probably a missing template error. If you don't specify any parameters in a format statement, Rails looks for and loads a file named action . format . template language (destroy.js.erb).
Try something like this:
format.js { render text: "Object successfully destroyed", status: :destroyed }
I have the following controller action:
def create
#board = Board.new(params[:board])
respond_to do |format|
if #board.save
set_board_session #board
set_new_board
format.js { render :action => "show" } #<== here I want to render html no js
else
format.js { render :action => "new" }
end
end
end
I want to render the show.html.erb action not the show.js.erb action for an ajax request.
How can I do this?
UPDATE
This seems to work for me:
I put this in my application controller:
def redirect_to(options = {}, response_status = {})
if request.xhr?
render(:show) {|page| page.redirect_to(options)}
else
super(options, response_status)
end
end
Now I can redirect with an Ajax call.
format.js {redirect_to #board}
Thanks to this forum:
Set dataType to "html" in your AJAX request and Rails will correctly handle AJAX request and render html, not js.
This seems to work for me:
I put this in my application controller:
def redirect_to(options = {}, response_status = {})
if request.xhr?
render(:show) {|page| page.redirect_to(options)}
else
super(options, response_status)
end
end
Now I can redirect with an Ajax call.
format.js {redirect_to #board}