I have a jQuery post submitting a form to a controller create action, which works great. If the save was successful I would like the create action to return a different form so the success callback will insert this form. Is this possible?
Here's my code:
def create
#event = Event.new(params[:event])
if #event.save
# This is where I would like to render a different controller action's view.
render :controller => "shows", :action => "new", :layout => false
else
render action: "new"
end
end
For some reason it will not render the "shows/new" template. It keeps rendering the current controller's new template without the layout. What am I missing here?
As an aside, I had a look at api.rubyonrails.org and tried to look up the render method. I found it listed as render(context,options), but can't for the life of me find out what the valid options are. This seems to be a common pattern for a lot of methods. How do I find out? It will certainly help me figure out what my options are, and perhaps give various things a try.
Thanks,
Dany.
ADDED: I have now used render "shows/new", :layout => false in my controller action, which is working. In my new.html.erb for Shows I have declared <%= render "/shows/form" %>. Unfortunately I am now getting 500 error. I found this in development.log:
ActionView::Template::Error (undefined method `model_name' for NilClass:Class):
1: <%= form_for(#show) do |f| %>
2: <% if #show.errors.any? %>
3: <div id="error_explanation">
4: <h2><%= pluralize(#show.errors.count, "error") %> prohibited this show from being saved:</h2>
app/views/shows/_form.html.erb:1:in `_app_views_shows__form_html_erb___1397093944823648986_2158339140'
app/views/shows/new.html.erb:3:in `_app_views_shows_new_html_erb__1152608637968596369_2158584080'
app/controllers/events_controller.rb:61:in `create'
I'm not entirely sure what's causing this...
Seems you missed: 2.2.3 Rendering an Action’s Template from Another Controller
Try:
render "shows/new", :layout => false
Related
I'm developing a litte blog like application and at the moment I'm facing a problem that I can't resolve.
I have 2 models at the moment :
1. Post
2. Comment
I can already manage my posts without difficulties but I have some problems with comments. I chose to make a relation has_many / belongs_to between my post and my comment models. I'd like to display all the comments related to a post when the user is on the post's page. My erb looks like this :
#some code
#...
#...
#render the comments
<%= render :template => "comments/index", :locals => {:post_id => #post.id} %>
My problem here is that the method index from my CommentsController is never called. I put some puts in the index method and they are never displayed in the console.
Should I use another tag to render the view ? Is there another way to do this ?
Thanks in advance for your help.
If the post view is the only page to show comments, you don't have to call comments/index to get comments, just show comments when rendering the post view, for example
In your post view
#some code
#...
# render comments
<% #post.comments.each do |c| %>
<%= c.content%>
# ...
<% end %>
Or put them in a partial with a post parameter if comments are used in many views
In app/views/partials/_comments.html.erb
# render comments
<% post.comments.each do |c| %>
<%= c.content%>
# ...
<% end %>
and render this partial where you want to show comments:
#some code
#...
# render comments
<%= render partial: "partials/comments", locals: { post: #post } %>
Using comments/index to get comments and showing them in a view is more likely the frondend tech such as Javascript/AJAX to load page parts dynamically. In this case, the comments/index is more likely an API call(render a JSON format instead of a html view).
I have this controller:
def index
#disclosures = Disclosure.where(:user_id => current_user.id)
respond_to do |format|
format.html{}
format.js{}
end
end
and with the help of the good folks at StackOverflow I am now able to get my HAML to point to the partial like this:
= render :partial => "/influencers/disclosures/shared/list"
but this partial throws and exception:
-if disclosures.empty?
.alert.alert-info
%p=(no_disclosures_message || (t "influencers.influencer_dashboard.disclosures.no_disclosures"))
%table.table.influencer-disclosures
%tbody
-disclosures.each do |disclosure|
=render "influencers/disclosures/shared/row", :disclosure => disclosure
saying that:
undefined local variable or method `disclosures' for #<#<Class:0x133ca8a58>:0x133ca25e0>
But how can this be? I just queried for that disclosures object in my controller. Any idea why this is happening and how to fix it?
Thanks!!
You need to put an # in front of disclosures. This is how the controller passes variables to the view.
-if #disclosures.empty?
and
-#disclosures.each do |disclosure|
Update
Another way to fix this is the change your render call. This will make it backwards compatible with other call sites of the same partial.
render :partial => "/influencers/disclosures/shared/list", :locals => {:disclosures => #disclosures}
In my rails application, I've got a partial view with an entry form on it. The form gets included on multiple pages across my app. The form in the partial posts to a RidesController to save with a create method like this:
RidesController.rb
def create
#ride = current_user.rides.build(params[:ride])
if #ride.save
flash[:success] = "Ride created!"
redirect_to root_path
else
#rides = current_user.rides.paginate(:page => params[:page])
render 'pages/home' # <---- WHAT GOES HERE?
end
end
I've commented the line where my question is. When we have an error, I need to present the same view that the user is presently on. But because this controller is being invoked from a partial instead of a full view, I don't know how to tell what context it's coming from.
Right now if there's an error on /rides/new, the user ends up redirected to the homepage which also has the form.
One way you could do this is pass the template path in with the form.
Add this to each main view that includes the form partial (e.g. pages/home, rides/new, etc):
<% #current_page_template = __FILE__ %>
In your form partial:
<%= form_for ... do |f| %>
<%= hidden_field_tag 'current_page_template',
#current_page_template.sub(File.join(Rails.root, 'app', 'views'), '') %>
In your controller:
def create
...
if #ride.save
...
else
...
render params[:current_page_template]
end
end
I want to render action inside my erb template.
<div>
<%= render :controller => :tags, :action => :tag_cloud %>
</div>
This block throws exception: undefined method `formats' for nil:NilClass
Also I want to tag_cloud action to be rendered from cache. Is that possible?
Regards,
Alexey Zakhaov
Just remind that render :action does not run the tags controller, it just renders the tag_cloud erb with the variables you have defined in your current controller.
So you have to define in your controller all the instance variables you need in your template, including the one on which the formats method is called.
I'm using form_remote_tag(:url => {:controller => "home", :action => "search"}, :update => "mydiv"). When I click submit on the form "mydiv" is populated with the error "Template is missing. Missing template home/search.erb in view path app/views". I've tried multiple render options in def search, but they all result in the same error.
It looks like the search method is trying to use it's default render even though I'm specifying what I want.
I've tried:
render 'index'
render :text => 'Return this from my method!'
Is my url incorrect? Is it not submitting back to my home controller's search method?
Try
render :action => 'index'
this will use "index.rhtml" or "index.html.erb".
I will try to explain why it said search.erb is not found, lets take create action for a some model, if there is some error in my create action they it will throw missing template create.html.erb file, since you have some error in your create action rails will try to render the create.html.erb in the page. Hope I explained it clearly.
In an ajax action you can't use redirect_to or render options directly.
try using this in your search action
render :update do |page|
page.replace_html "ur_div_id","partial"
end
The form_remote_tag needs prototype to function. Make sure you are including the :defaults for your javascript libraries namely prototype.
<%= javascript_include_tag :defaults %>