I am using render :layout => false for my new action.
All works fine, until I submit the form with validation errors. The create action calls render :new and I see the form, with the bullets outlining the errors. The issue is that the form now renders with application layout and seems to be ignoring the render :layout => false.
From what I can tell I believe this is because I am not actually redirecting to :new, just rendering the :new view whilst still in the create action. I cant add render :layout => false to the create action, because rails only allows one render per action.
Is there a way to get the form with validation errors to not use the application layout? I still want the bullets with the validation errors.
Apologies, looks like I worked this out. Thought I had tried this but must have been a syntax error before.
The solution is to add render :new, :layout => false to your create action.
Iam not sure, but you can use a
layout :false, only: [:create]
hope this may help.
Related
else
respond_to do |format|
format.html { render "tabelle/show" }
end
end
I want to render the page ...with only the code in that page....not add <head>...layout and <body> field in ruby on rails.
I only want to show the result of code in the page tabelle/show.html.haml
You can do it like this:
format.html { render "tabelle/show", :layout => false }
Controller:
layout false, only: [:method_name]
this is very useful when you using render_to_string
add
:layout => false
Example:
render "tabelle/show", :layout => false
If you do not want to specify the view to use.
Rails is smart enough to know which view template to use based on the Controller Action you're on.
For example, if you're on the show action of the TabellesController you wouldn't need to specify render "tabelle/show" in your Controller Action because Rails will already assume that and will automatically try to render the file in app/views/tabelles/show.html.erb.
So if you're sticking with all of those defaults then you can just use the following to render without the typical layout template:
def show
# Other stuff in your Controller Action.
render layout: false
end
This will render app/views/tabelles/show.html.erb but without the layout template automatically.
Noice.
I'm building my first rails app just right now and now I have a problem.
I have an application layout which includes an header and a footer (and of course the content). Now I have a popup in one view (I use Facebox) which works well, except I don't want to show the footer in the page loaded via ajax.
I don't know how I can do that ... is there a way how I could add something like this option to the URL?
I would already be very happy if you could just give me an idea how to solve this problem.
Do you need to change layout of a page that is shown inside the popup? If so, check please :layout options of the render method. You can use another layout, or no layout at all.
You can do it in your controller. Either create new action for "footerless" page (don't forget to modify routes.rb)
def show_footerless (user/1/show_footerless)
#user = User.find(params[:id])
render "show", :layout => "footerless" # or :layout => nil
end
Or pass extra param to standard action (/user/1?footerless=1)
def show
#user = User.find(params[:id])
if params[:footerless]==1
render "show", :layout => "footerless" # or :layout => nil
else
render "show"
end
end
You can do, when opening the popup
#popup_displayed = true
Then in the layout
<%= render 'layouts/footer' unless #popup_displayed %>
I would like to specify a specific view file to render instead of the default one corresponding the REST architecture, meaning out of my 'create' function in the controller I would like to invoke the 'new' view file - which I believe can be done using:
def create
.
.
render :new
end
But I also need that view file to ignore the cross-site layout specified in layouts/application.html.erb? is there a way to do that?
If it was out of the 'new' function, I could just state "render :layout => false" .. but I need it out of the 'create'
is there something like:
render :new, layout => false
Thanks!
Another way is this:
render :template => :new, :layout => false
I' not sure about that, would have to try it, but i think that you can do this :
layout 'application', :except => :action_name
to exclude the action in your controller.
EDIT : I just tried it, it works indeed :)
You can do what you mentioned
def create
render :new, :layout => false
end
You can then add the conditions like this
def create
render :new, :layout => user_signed_in?
end
or the other way around depending on your need
I am currently having an issue with how Rails is performing and responding to a validation result. I have a user registration form. The user could hit this form in two different places. They could hit the form from the homepage or from users/new. Both forms will post to the same place as I am trying to keep it DRY.
The users/new page works as is expected. If the user has a validation issue it will return and populate the form. Where I get a problem is on the home page. If a user has a validation issue it now redirects to the users/new page. I would much prefer that when on the home page I would return the user to that same page and show the validation results there. Is there a way in the controller to redirect to the form the user was at?
def create
#user = User.new(params[:user])
respond_to do |format|
if #user.save
format.html { redirect_to(#user, :notice => 'User was successfully created.') }
format.xml { render :xml => #user, :status => :created, :location => #user }
else
format.html { render :action => "new" } # I'm thinking I can do something here?
format.xml { render :xml => #user.errors, :status => :unprocessable_entity }
end
end
end
I have tried to change the render :action => 'new' line to redirect to the user url but it hasn't worked. Is there something I'm missing?
First, I would add querystring parameters to the URL it is posting to with the controller and action that it came from with something like this:
# Using form_tag
<%= form_tag user_path(#user, :controller_name => controller.controller_name, :action_name => controller.action_name) do %>
# Using form_for
<%= form_for #user, :url => user_path(#user, :controller_name => controller.controller_name, :action_name => controller.action_name) do %>
Then, you can update that line in the create action of your controller like this:
render '#{params[:controller_name]}/#{params[:action_name]}'
Update
I just realized that using the code above, will render the correct view the first time validation fails, but if validation fails a second time, it will try to render the users/create view. If this is the route you want to take, you should not use controller.controller_name, etc in the view, but assign #controller_name correctly and use that variable instead. However, this only adds to the 'overkill' comment made by Xavier.
Art's on the right track, but you can't use a redirect, as you need the instance variable #user that's set in your controller, which'll be lost on a new HTTP request (because ever request is handled by a new, clean controller instance).
But you can use the referer information yourself, and use that to pick the right page to render:
render :action => (request.referer =~ /\/users\/new/)? :new : :index
Note: Another answer popped up while I was posting that suggests adding the old controller / action fields to your form, but that seems like overkill to me - you already have all the information you need in request.referer.
Hope that helps!
Try redirect_to :back
It's a shorthand for redirect_to(request.env["HTTP_REFERER"])
oops, it only works for success. sorry
well, then you have to check inside the block (after format.html) where he came from (by looking at request.env["HTTP_REFERER"]) and render respective action.
So.. I have this in the action called when someone clicks the archive button
respond_to do |format|
format.js do
render :update do |page|
page << "alert('You have reached your archive object limit. You have #{remaining} remaining archived objects.');"
end
end
end
But instead of alerting, it just gets rid of the entire page and shows a JavaScript try / catch with that alert message. How do I just do an alert without rendering anything?
Add
:layout => false
in render
Needed to change form_for to form_remote_for to enable ajax
If it's an AJAX call, you may do something like this in your action:
render :text => "<script type='text/javascript'>alert('bla');</script>"