Render a partial instead or in a flash notice - ruby-on-rails-3

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.

Related

How to give option for multiple templates for one view?

I have an application in rails3 where i want to give user an option to choose a template from defaults (4 or 5 templates) to view his records.
the approach i am working on is to sent user on setting page from where he will select the template he want to use and on the basis of that setting the template will be rendered.
This looks simple but i am not sure this will work for me, please suggest me any alternative.
Please note i am talking about PDF formats.
Let's say you have a Setting model with a string attribute template.
You would let the user save the setting through a normal controller action.
Then on the controller where you want your pdf template to show, you could do something like this.
class MyController < ApplicationController
def show
#setting = Setting.find(params[:setting_id]) # Retrieve the setting instance
respond_to do |format|
format.pdf { render setting.template }
end
end
end
This will render the template named after the template the user has selected and is stored on setting as a string.

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

Where does Rails' respond_to block parameter get xml, html, json members?

Generating a scaffold like this:
rails generate scaffold User name:string email:string
creates bits of code that look like this in the controller class:
respond_to do |format|
format.html # show.html.erb
format.json { render json: #user }
end
At first I didn't know what this meant, so I went looking and found this,
which I think adequately explains most of it. But format is supposed to end up being a Responder class. Well, there doesn't seem to be any xml or html or json members declared in the Responder class. Where do they come from?
PS:
It seems cruel that the scaffold developer would name the block parameter "format" when it ends up being a Responder (and the format information comes from the .html, .xml, .json, or whatever) to make the code sound a bit like English but hinder understanding of what's actually going on. In fact, Responder::respond is defined like so, which seems too coincidental:
def respond
method = "to_#{format}"
respond_to?(method) ? send(method) : to_format
end
But I don't see how the format here (in "to_#{format}") can be related to the block parameter named format. And to be clear, it's NOT an instance variable because it's lacking an # sign, right?
As the blog explains later, basically from here the Responder instance handles .html and .xml via method_missing, depending on mime types your rails app can process.
One of the nice blogs that describe method_missing is here.
Basically, the responder's method_missing will get called when js and json methods are invoked. The method_missing of responder class will get the "missing method_name" (that is, :js or :json symbols) as its first parameter, which will drive its rendering logic.

Rails is responding with wrong format

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

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