respond_with/to rendering wrong view - ruby-on-rails-3

I'm trying to understand why respond_with/to is rendering the wrong view...
controller
respond_to :html, :js
def get_numbers
Rails.logger.info request.format
#numbers = Number.all
respond_with #numbers
end
when making an ajax request, the rails log shows the format is JS, and the request format is text/javascript, but it renders the html view.
log
Started GET "/numbers/get_numbers?_=1333564838110" for 127.0.0.1 at 2012-04-04 11:40:38 -0700
Processing by NumbersController#get_numbers as JS
...
text/javascript
Rendered numbers/get_numbers.html.haml within layouts/application (106.4ms)
and i have both a get_numbers.html.haml & get_numbers.js.coffee view in views/numbers
i could render the correct view by doing:
respond_with #numbers do |format|
format.js {}
end
but shouldn't it be rendering the js view with just respond_with #numbers

If you want the response to be JavaScript when no format is explicitly specified (meaning no .html or .js in the URL), you can set the default format parameter in your route:
match '/numbers/get_numbers(.:format)' => 'numbers#get_numbers', :defaults => { :format => :js }
You might also get your desired results by switching the order of the formats in your call to respond_to, since it seems to default to the first one, but I haven't tested that.

Related

What does (.:format) mean in rake routes' output?

What does (.:format) mean in rake routes' output?
users GET /users(.:format) users#index
If you check the index action of your Users Controller then you will see something like this
def index
#users = User.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #users }
end
end
So, this format is the type of response which will be generated.
In routes, a placeholder for the type of response is created irrespective of whatever format has been defined in the action of the controller.
So, if your URL is something like :-
users GET /users --> users/index.html.erb will be rendered
users GET /users.json --> users/index.json.erb will be rendered
Similarly, if you want response in PDF or xls format, then you just have to define format.pdf or format.xls and also you have to define these new MIME types which are not there by default in rails in some initializer file.
So, then if a request is made like :-
users GET /users.xls --> users/index.xls.erb will be rendered
Your routes file will then just look for the format.xls in the index action and respective view file means users/index.xls.erb will be rendered.

How to render JSON in Rails view

I've tryed the solution of following example: In Rails, how do you render JSON using a view?
But my problem is that the database already has a JSON string saved, I pull the json string and then I should be able to display the JSON file in the the view.
I'm using this because an android tablet should be able to visit the same url but depending on its settings (send by a POST) a different JSON file should be displayed, the android tablet then fetches the json and use it to configure some options.
So I already have a full working json file, i'm looking for a way to display it in a view (without rendering html tags and other stuff). I tryed the following (yes I've added respond_to :json) :
# def show_json (#config is the record, #config.json_config is the actual json configuration file
#config = event.et_relationships.where(terminal_id: terminal).first
respond_to do |format|
format.json
end
Then my view I have
#show_json.json.erb
<%= #config.config_json %>
Then the HTML I get to see (no errors are given)
<html><head><style type="text/css"></style></head><body></body></html>
Thanks!
EDIT
I'm using rails 3.2.3
Here is my routes (only relevant parts)
match '/events/config', to: "events#show_json", as: :show_json
resources :events do
member do
get :select_item
get :category
end
end
Then also the controller (partial)
respond_to :html, :json, :js
def show_json
#terminal_id = params["mac"]
terminal_id = "3D:3D:3D:3D:3D:3D"
event = current_user.events.where("date(endtime) > ? AND date(starttime) < ?", Time.now.to_s, Time.now.to_s).first
if event.nil?
# Nothing got returned so we use the default event
event = current_user.events.where('"default" = ?', true).first
end
logger.info "MAC: #{terminal_id}"
terminal = current_user.terminals.where(serial: terminal_id).first
logger.info "Terminal: #{terminal.attributes.inspect}"
logger.info "#{event.attributes.inspect}"
#config = event.et_relationships.where(terminal_id: terminal).first
logger.info "CONFIG #{#config[:config_json]}"
respond_to do |format|
format.json { render json: #config[:config_json] }
end
end
Use render:
#config = event.et_relationships.where(terminal_id: terminal).first
respond_to do |format|
format.json { render json: #config }
end
And then you have path /:model/:action.json.

Why is Rails 3.2.2 Generating URLs prefixed with /assets when using redirect_to?

Well the title Question pretty much sums it up, But I'd like to detail a scenario anyways,
I've created a DemoController, (I have not created a Resource model), and my routes.rb looks like this:
DispatchMe::Application.routes.draw do
root to: "demo#index"
end
From the demo controller I'm dong the following:
class DemoController < ApplicationController
def index
redirect_to :action => 'show'
end
def show
end
end
There is a file in: app/views/demo/show.html.erb of course, And I'd expected that template to be rendered but instead I'm getting the following error:
ActionController::RoutingError (No route matches [GET] "/assets")
and this URL is generated as a result from the redirect:
/assets?action=show&controller=demo
Am I missing something here? I thought rails was supposed to render the action's template for such cases.
Note. I understand that If I create a route like get 'show' => "demo#show" and call redirect_to show_path it'll work just fine, But I need to know if that's mandatory?
Thank you very much!
For the desired behavior, use render instead of redirect_to:
class PagesController < ApplicationController
def index
render :action => "show"
end
def show
end
end
EDIT:
You can use redirect_to on other actions, but from what I can tell, the index action sets the base path. To simplify route definition, use resources :controller_name. You can view the routes generated by resources by typing rake routes in your command line.
Example:
demo_controller.rb
class DemoController < ApplicationController
def index
end
def show
redirect_to :action => 'index'
end
end
routes.rb
DispatchMe::Application.routes.draw do
root to: "demo#index"
resources :demo
end
development.log
Started GET "/demo/show" for 127.0.0.1 at 2012-04-04 14:55:25 -0400
Processing by DemoController#show as HTML
Parameters: {"id"=>"show"}
Redirected to http://dispatch.dev/
Completed 302 Found in 0ms (ActiveRecord: 0.0ms)

not able to load a view when I disable javascript rails 3

Here is my controller code:-
def image_test
respond_to do |format|
format.js {render :layout => false}
format.html {redirect_to image_test_path}
end
end
I have got a partial by the name of _image_test.html.erb and and a simple view image_test.html.erb
In my routes I have done this:-
match "/image_test", :to => "/index#image_test"
It works fine when the javascript is enabled in the borwser however when I disable the javascript I want it to redirect me to my image_test.html.erb file. Instead I get a no route match error.
Please help me with this.
Thanks,
I created a workaround for this solution which is giving the desired result of redirecting to another page if javascript is disabled in a browser but I do not know if this is the rails way.
I created empty action corresponding view for those actions and redirected to those views in case javascript is disabled.
Here is an example of what I did :-
def javascript_enabled_view
respond_to do |format|
format.js {render :layout => false}
format.html {redirect_to :action => "javscript_disabled_view"}
end
end
I have got a corresponding js.erb file and the partial for the above action which will work if javascript is enabled in the browser.
def javascript_disabled_view
end
I have got the corresponding html.erb file which will work in case javascript is disabled in the browser.
Thanks,

After deleting a record in Rails 3, the refreshed view isn't updated

I'm dealing with a basic one to many relation where I'm deleting a record on the many side. The models are "places" and "search_terms" where places has_many search_terms. When I create a new record, the view is updated and the new search_term appended to the list. However, when I delete a search_term record the view is not refreshed even though it deletes the record and runs the "show" method for Place.
I'm quite new to rails 3 so can't really figure out whats going on here...
Cheers,
Gearoid.
Edit: the search_terms controller destroy method:
def destroy
#search_term = SearchTerm.find(params[:id])
#search_term.destroy
#place = Place.find(params[:place_id])
redirect_to place_path(#place)
end
The places controller show method:
def show
#place = Place.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #place }
end
end
I might be misunderstanding you, could you post your controller's code?
Is this happening over ajax? If not, can you redirect to the Show instead of just re-rendering it? That's probably a preferred experience for the user anyway.
UPDATE
Ok, if this is going over ajax, then the problem is simple. Your destroy action is only expecting a normal browser event and doing a redirect_to call. The ajax call doesn't know how to handle it and just sits there. You can probably see the redirect code in something like Firebug.
I'm not super familiar with jquery-rails (I prefer to write all my js myself because I'm anal). You can have the destroy action return a js format like so:
def destroy
#search_term = SearchTerm.find(params[:id])
#search_term.destroy
#place = Place.find(params[:place_id])
respond_to do |format|
format.html { redirect_to place_path(#place) }
format.js { render :nothing => true }
end
end
That will give the ajax caller the ok signal that it has done its thing. Your javascript will still have to intelligently handle this response though, like remove the element from the DOM.