I have a route that I need to call like so:
/images/get_subcollections.json?id=1234
I have this in my routes file:
resources :images do
collection do
get 'get_subcollections'
end
end
I have this in my controller:
def get_subcollections
collection = Collection.find(params[:id])
respond_to do |format|
format.json { render :layout => false, :json => collection.to_json(:methods=>:get_subcollections) }
end
end
The app just sits there when I call the URL. The request doesn't get logged or anything. Any ideas? Thanks!
Have you inspected the response using firebug or chrome's dev tools? Is it just that layout: false is stopping you seeing anything?
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 have rabl up and running.
I have this in routes:
get 'biblios/collection/:biblio_urn' => 'biblios#biblio_rabl', as: 'collection_biblio'
in the controller:
def biblio_rabl
biblio = Biblio.where(biblio_urn: params[:biblio_urn]).take
end
This url points to the correct result :
http://localhost:3000/dts/biblios/collection/urn:cts:froLit:ed_desmarez:1900
I would like that url to always respond using rabl and showing the the template dts/biblios/biblio_rabl.json.rabl
I mean without adding .json at the end of the url.
I have tried this in the routes.rb, but it doesn't redirect :
get 'biblios/collection/:biblio_urn' => 'biblios#biblio_rabl', as: 'collection_biblio', to: redirect('biblios/collection/%{biblio_urn}.json')
Is that possible at all?
You can force the response to be json by changing the request format in the controller:
request.format = :json
Then make sure you have a respond_to block like this because it's always better to be explicit about your responses:
def biblio_rabl
respond_to do |format|
format.json { json: Biblio.where(biblio_urn: params[:biblio_urn]).take }
end
end
I am creating a basic product landing page with Rails in which users can enter their email address to be notified when the product launches. (Yes, there are services/gems etc that could do this for me, but I am new to programming and want to build it myself to learn rails.)
On successful submit of the form, I would like to redirect to a custom '/thanks' page in which I thank users for their interest in the product (and also encourage them to complete a short survey.)
Currently, successful submits are displayed at "/invites/:id/" eg "invites/3" which I do not want since it exposes the number of invites that have been submitted. I would like to instead redirect all successful submits to a "/thanks" page.
I have attempted to research "rails custom URLs" but have not been able to find anything that works. The closest I was able to find was this Stackoverflow post on how to redirect with custom routes but did not fully understand the solution being recommended. I have also tried reading the Rails Guide on Routes but am new to this and did not see anything that I understood to allow for creating a custom URL.
I have placed my thanks message which I would like displayed on successful form submit in "views/invites/show.html.haml"
My Routes file
resources :invites
root :to => 'invites#new'
I tried inserting in routes.rb:
post "/:thanks" => "invites#show", :as => :thanks
But I don't know if this would work or how I would tell the controller to redirect to :thanks
My controller (basically vanilla rails, only relevant actions included here):
def show
#invite = Invite.find(params[:id])
show_path = "/thanks"
respond_to do |format|
format.html # show.html.erb
format.json { render json: #invite }
end
end
# GET /invites/new
# GET /invites/new.json
def new
#invite = Invite.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #invite }
end
end
# POST /invites
# POST /invites.json
def create
#invite = Invite.new(params[:invite])
respond_to do |format|
if #invite.save
format.html { redirect_to #invite }
#format.js { render :action => 'create_success' }
format.json { render json: #invite, status: :created, location: #invite }
else
format.html { render action: "new" }
#format.js { render :action => 'create_fail' }
format.json { render json: #invite.errors, status: :unprocessable_entity }
end
end
end
It would seem as if creating a standard URL for displaying a confirmation would be relatively straightforward. Any advice on how to achieve this would be appreciated.
I guess you want to redirect after your create action, which is executed when the form is submitted.
Just add redirect_to in the following way:
def create
#invite = Invite.new(params[:invite])
if #invite.save
...
redirect_to '/thanks'
else
...
redirect_to new_invite_path # if you want to return to the form submission page on error
end
end
I omitted some of the code for brevity.
In your routes add:
get '/thanks', to: "invites#thanks"
Add the thanks action to your invites controller:
def thanks
# something here if needed
end
And create a thanks.html.erb page in app/views/invites.
I would do get "/thanks" => "invites#thanks" in routes.rb and then add this in your controller:
def thanks
end
Then add a file app/views/invites/thanks.html.erb with your thank-you content.
You could create a route like this:
resources :invites do
collection do
get 'thanks'
end
end
This will also create a path helper called thanks_invites_path.
It will be at the invites/thanks path, but if you want it to be on/thanks, you could just do as Jason mentioned:
get "/thanks" => "invites#thanks", :as => :thanks
The as part will generate a helper to access that page: thanks_path.
You would need a extra action in the controller called thanks, and put whatever info you need inside, and also you will need a additional view called thanks.html.erb
Since you want everybody to go to that page after a successful submit, in your create action you would have:
format.html { redirect_to thanks_invites_path} (or thanks_path), what ever you choose, when you name the route you can check it with rake routes if it's okay, and whatever rake routes says, just add _path at the end.
I have a particular Rails controller method that returns some JSON when I do an javascript ajax request in the front-end.
However, I want to prevent users from directly typing in the url, which displays the JSON that the method returns. I also want to still be able to perform my ajax requests. How can I go about doing this simply? Thanks!!
Just a thought... You could do something custom in your respond_to block for html requests.
respond_to do |format|
format.html { ... } # give them a 404 response?
format.js { render :json => #obj }
end
Or maybe your html.erb template with that name could just show some kind of access denied message. Then you'd just have this:
respond_to do |format|
format.html
format.js { render :json => #obj }
end
You could wrap your action with
if request.xhr?
...
end
The respond_to filter in rails3 controllers is pretty sweet.
YourJsonController < ApplicationController
respond_to :json
def index
#non-json requests will receive a 406 error
end
end
In your routes.rb, you can add :via => :post so your URL accepts only POST requests. See "HTTP Verb Constraints" at http://guides.rubyonrails.org/routing.html
I want to explicitly call a view from my controller.
Right now I have:
def some_action
.. do something ...
respond_to do |format|
format.xml
end
end
... then it calls my some_action.xml.builder view. How can I call some other view? Is there a parameter in respond_to I'm missing?
Thanks,
JP
You could do something like the following using render:
respond_to do |format|
format.html { render :template => "weblog/show" }
end
See the Rendering section of the ActionController::Base documentation for the different ways you can control what to render.
You can tell Rails to render a specific view (template) like this:
# Renders the template located in [TEMPLATE_ROOT]/weblog/show.r(html|xml) (in Rails, app/views/weblog/show.erb)
render :template => "weblog/show"
# Renders the template with a local variable
render :template => "weblog/show", :locals => {:customer => Customer.new}
Or even simpler since Rails > 3.0:
render "edit"
You can also pass :action, or :controller if that's more convenient.
respond_to do |format|
format.html { render :action => 'show' }
end
You can modify the internal lookup_context of the controller by doing this in your controller
before_filter do
lookup_context.prefixes << 'view_prefix'
end
and the controller will try to load view/view_prefix/show.html when responding to an show request after looking for all the other view prefixes in the list. The default list is typically application and the name of the current controller.
class MagicController
before_filter do
lookup_context.prefixes << 'secondary'
end
def show
# ...
end
end
app.get '/magic/1`
This GET request will look for a view in the following order:
view/application/show.erb
view/magic/show.erb
view/secondary/show.erb
and use the first found view.
Use render
http://api.rubyonrails.com/classes/ActionController/Base.html#M000474