Rails is responding with wrong format - ruby-on-rails-3

I have the following action:
def something
# do something
respond_to do |format|
format.js
end
end
I also have an something.html.erb template in my controller.
When I GET /controller/something, it returns nothing.
When I GET /controller/something.js, it renders the html with no layout.
When I XHR GET /controller/something, it renders the html with no layout.
I would expect it to "return a template not found error" error instead of rendering the html template.
Is this a bug of Rails or am I doing something wrong?
rails v3.0.4
ruby v1.9.3

I think it's because of the “convention over configuration” principle. If you don't specify a render or redirect_to in the action of the controller, rails renders the view with the same name as the method. Look at Rails render guide

Related

Render a partial instead or in a flash notice

I'd like to render a partial or similar in lieu of a simple flash notice. This is how it exists currently:
format.html { redirect_to share_url(#doc), notice: "#{#doc.title} has been created. You may #{view_context.link_to('edit', edit_doc_url(#doc))} it further, #{view_context.link_to('finalise', lock_doc_url(#doc))} it, or return #{view_context.link_to('home', root_url)}.".html_safe }
I'd like to render a partial or similar instead of the notice so I can customise it more.
Any thoughts? Thanks!
You could probably do it this way:
format.html { render action: "my_error_messages" }
Then create a my_error_messages action inside the same controller and create a corresponding view and route for it. Then customize the html/haml as you'd like.
Another approach might be to customize the messages partial for your flash messages which is most likely being called within your application layout. You'd likely find it in your apps/views/layouts directory.

Is there any issue with using respond_to blocks in controller actions like this?

I'm AJAXifying an existing Rails 3.2 application, and some of the requests that are made from the client are better done asynchronously. To facilitate this, and to cut down on rendering time, I'm giving feedback to the user via alerts. I have a blank div in my application.html.erb file that I add alerts to as needed from certain controller actions like so:
def my_async_controller_action
#user = User.find(params[:id])
begin
##user.import
flash[:notice] = "Your data is being downloaded."
rescue Exception => bang
flash[:alert] = "There was an error downloading your data: #{bang.message}"
end
respond_to do |format|
format.js { render 'common/flashes' }
end
end
And my common/flashes file just uses jQuery to append the alerts to the blank div. While it works fine, I have never seen alerts delivered like this, only via redirects. Is there any unwritten (or written) Rails convention or rule that I'm breaking by taking this approach? Also, is there a way to instead do this as a respond_with? I can't see how I do two different types of rendering from a single line.
If the js file you are rendering has the same name as the action of your controller, you don't need a respond_to block.
However, since you are placing your js file in a common folder, to reuse among your controllers, you have to explicitly tell Rails to render that file. This is totally fine.
If your action only responds to js, you can use brackets instead of a do ... end block to make it a one liner:
respond_to { |format| format.js }
However, since you have to specify the name of the js file, this can get quite ugly, so you can omit the respond_to block and just do the following:
render 'common/flashes'
This, however, has the inconvenient that if your controller receives an html request, it will search for a file named flashes.html inside the common folder. This will most likely return a Template is missing error. If you want to fix that, you have to add some constraints to the format.
However, if your action also responds to html, then you should declare the block like this:
respond_to do |format|
format.html
format.js { render 'common/flashes' }
end
You don't need the format.html, but when you look at the code, you can immediately tell that it responds to both html and js requests.
Using a respond_with block to render different files isn't applicable in your case, since you are only rendering some javascript. respond_with is used to return some resource in various formats (html, json, xml). This article goes into a little more detail.
respond_to do |format|
format.js
end
I see no problems from the side of your controller.
Just be sure to use escape_javascript when rending in your .js.erb

wicked_pdf handlebars/mustache support

I've used wicked_pdf with erb before, but I'm now wanting to use wicked_pdf leveraging handlebars as my template engine.
Should that just work with wicked_pdf? I see questions with haml tags, so I'm assuming yes. Just wondering if anyone else has tried.
On a side note - Is anyone using presenters with wicked_pdf?
It should work.
WickedPdf merely hooks into the Rails 'render' method, so anything it can do, can be done with wicked_pdf.
When I use haml I do the following, perhaps something similar is possible with handlebars.
def [action-name]
...
respond_to do |format|
format.html
format.pdf do
render :pdf => 'filename',
:handlers => [:haml]
end
end
end

Render page doesn’t exist Like Twitter in rails 3

How do I render a 404 or page doesn't exist like Twitter does?
I use rails 3.2.3
My code
def rescue_with_handler(exception)
redirect_to '/500.html'
end
def method_missing(id, *args)
redirect_to '/404.html'
end
That works, but I want to be like twitter. For example if I access this page
https://twitter.com/abcd/skka/asafaga
and https://twitter.com/abcd/skka
You have to handle Routing Error with rescue_from.
This question was already answered:
Dynamic error pages in Rails 3
Best way to handle 404 in Rails3 controllers with a DataMapper get
rescue_from NoMethodError
...
Also there is solution here:
https://github.com/rails/rails/issues/671
In any case, try to Google it, you will find a lot of different solutions.

Render a page as a saved HTML file using Rails 3.0?

I'm building a simple website generator application in Rails 3.0. I'd like a "publish" action in a controller that works just like an ordinary "show" action, but instead, saves a page as an HTML file in the "public" directory instead of displaying it in the browser. That is, I'd like to use the Rails render mechanism to create a file instead of providing an HTTP response.
What's the best way to do this?
Should I simply add caches_page :publish to the controller?
Or use render_to_string and File.new?
You can use render_to_string method: http://apidock.com/rails/AbstractController/Rendering/render_to_string
You still need to respond from the controller though. Maybe redirect to the page you just saved?
I would go with page caching.
Then if you have editable content, the pages should be automatically generated. You could then write a system task which bundles them up as a web site.
see (whatever)/actionpack/lib/action_controller/caching/pages.rb for instructions.
I found that page caching using caches_page won't work for me because there is no way to show a notification or redirect to another page after caching the page. The method render_to_string (suggested by #Grocery) is the way to go. Here's the example controller code:
def publish
#article = Article.find(params[:id])
html = render_to_string(:template => "articles/template.html.haml", :layout => 'article' )
FileUtils.makedirs("#{Rails.root}/public/articles/") unless File.exists?("#{Rails.root}/public/articles/")
File.open("#{Rails.root}/public/articles/#{#article.filename}.html", 'w') {|f| f.write(html) }
respond_to do |format|
format.html # publish.html.erb
end
end