Rails: render partial with selected controller and action in view - ruby-on-rails

I have a Rails app where on the home page home/index.html.erb, I show a partial for the model workorders. It currently defaults to the home_controleer.rb with the action index.
Can I select the workorders_controller.rb and action index2?
I tried this in the home/index.html.erb view file:
<%= render :partial => "workorders/index7", :controller => "workorders", :action => "index2" %>
But it's not working.

Try this instead:
<%= render :template => "workorders/index2" %>
source: https://stackoverflow.com/a/6051812/2128691
edit: in response to your last comment...
I haven't really worked with bootstrap, but maybe you could do something like this [pseudocode]:
def home
if [x condition]
redirect_to index_seven_path
else
render :action => [y action]
end
end

Related

Need to pass parameters to ajax file

I have a web page with a couple of buttons and each button loads information on the page through ajax. Each button calls the same action in controller. That action, called "load" then calls an ajax file which in turns loads different information on the page depending on which button was clicked.
My buttons in my html file look like this.
<%= button_to "Load Profile", { :controller => "surveys", :action => "load"} %>
<%= button_to "Load Personality", { :controller => "surveys", :action => "load"} %>
<%= button_to "Load Experience", { :controller => "surveys", :action => "load"} %>
The load action in the surveys_controller.rb file looks like
def load
respond_to do |f|
f.js { render 'shared/ajax/info.js.erb' }
end
end
The info.js.erb file looks like this
$('#email').empty().html("<%= j render(:partial => 'shared/survey/tech/profile') %>")
This has worked for me in other places but now the content i need to load differs. I need the "#email" and the "shared/survey/tech/profile" to be a parameter sent from the load action. Can anyone help me?
Since you have the same action and same js.erb file for each button therefore you need to send some data using your buttons in order to differentiate with of the buttons is clicked.
For that you need to follow these steps:
a. Create a post request for your custom method load
post 'surveys/load' => "surveys#load"
b. Send some data through your buttons which will differentiate them:
<%= button_to "Load Profile", { :controller => "surveys", :action => "load", :profile => "yes"} , :method=>:post, :remote => true %>
# this will make you access params[:profile]
c. Check inside your load method which button is being clicked using params:
def load
#profile = params[:profile]
#other params to store values of personality and experience
respond_to do |f|
f.js { render 'shared/ajax/info.js.erb' }
end
end
d. Inside your info.js.erb file you could check which one of the variable is equal to yes and then render accordingly
<% if #profile == "yes" %>
#render your partial
<% elsif #personality == "yes" %>
#render your partial
<% elseif #experience == "yes" %>
#render your partial
<% end %>
On a second thought i think it'll be better if we just separate out this logic inside controller and depending on the params value render different js files like:
def load
#profile = params[:profile]
#other params to store values of personality and experience
if #profile == "yes"
respond_to do |f|
f.js { render 'shared/ajax/profile_info.js.erb' }
end
elsif #personality == "yes"
respond_to do |f|
f.js { render 'shared/ajax/personality_info.js.erb' }
end
end
end
Try something like this and see if it works for you;
<%= link_to "Load Profile", { :controller => "surveys", :action => "load"}, remote: true %>
<%= link_to "Load Personality", { :controller => "surveys", :action => "load"}, remote: true %>
<%= link_to "Load Experience", { :controller => "surveys", :action => "load"}, remote: true %>
respond_to do |form
format.js { }
end
and then;
$('#email').empty().html("<%= j render(:partial => 'shared/survey/tech/profile') %>")

Getting "Template is missing" error when attempting to render js.erb file

I'm new to Rails, and I'm having an issue where I can't render a .js.erb file. I think the root of the issue is that Rails' internal routing mechanism expects me to name and configure my files just so, but I'm missing one or two pieces, and I'm not sure how to look for what needs to be fixed.
I have an HTML view with a link to a controller action:
<%# snip %>
<div id="holding_issues_list">
<%= link_to "Show issues on hold", {
:action => "show_user_issues",
:controller => "support",
:issue_type => "holding",
:user_id => #user.id },
:remote => true %>
</div>
<%# snip %>
I think (but I'm not sure) that :remote => true causes the link to make an AJAX call.
This is the corresponding controller action in the controller app/controllers/support_controller.rb:
def show_user_issues
#target_div = params[:target_div] || "holding_issues_list"
user = User.find(params[:user_id])
issue_type = params[:issue_type]
#snip - set the value of #issues
end
I want this file, named show_user_issues.js.erb and placed in app/views/support, to be rendered when the controller exits:
$("#<%= #target_div %>").show();
alert('test');
$("#<%= #target_div %>").html(
"<%= escape_javascript render :partial => '_show_user_issues', :locals => {:target_div => #target_div, :issues => #issues} %>");
This is app/views/support/_show_user_issues.html.erb, the partial I want show_user_issues.js.erb to render:
<% for issue in #active_issues %>
<div id="issue_<%= issue.id %>_display">
<%= render :partial => 'show_issue_mini', :locals => {:issue => issue} %>
</div>
<% end %>
When I try clicking the link in my original HTML view, nothing happens. When I open it up in a new tab, I get this error message:
Template is missing
Missing template support/show_user_issues,
application/show_user_issues with {:locale=>[:en],
:handlers=>[:builder, :erb], :formats=>[:html]}. Searched in: *
"/home/<>/app/views" *
"/home/<>/gems/kaminari-0.14.1/app/views"
The alert('test') that I put into show_user_issues.js.erb doesn't show up, so I think that Rails is getting hung up on rendering that file - that is, the routing mechanism can't find it. How can I correct this issue?
P.S. I double-checked that I put in all the file names exactly as they are in the code base.
Change your controller action to handle the type of request.
def show_user_issues
#target_div = params[:target_div] || "holding_issues_list"
user = User.find(params[:user_id])
issue_type = params[:issue_type]
#snip - set the value of #issues
respond_to do |format|
format.js
end
end
This will check the format of the request which is .js in case of :remote => true. So it will handle it by rendering the show_user_issues.js.erb file.
A couple other problems that I ran into after applying Manoj Monga's answer that I suspect other new Rails devs might run into:
In show_user_issues.js.erb, I had
[...].html("<%= escape_javascript render :partial => '_show_user_issues',[...]
The underscore before '_show_user_issues' caused the ERB builder to fail. It should have just been 'show_user_issues'.
In _show_user_issues.html.erb, I had
<% for issue in #active_issues %>
If you look closely at show_user_issues.js.erb, though, I named the variable #issues, not #active_issues:
[...]:locals => {:target_div => #target_div, :issues => #issues}[...]
So I changed the line in the HTML partial to
<% for issue in #issues %>
After these last couple changes, the new functionality I was adding worked as expected.

where does render :partial html end up

I have a view with an ajax form:
<%= form_tag( {:action => 'some_action'}, {:remote => true}) do %>
...
<%= submit_tag "Submit" %>
<% end %>
Now, in the target action, I want to display a partial
def some_action
# some logic
render :partial => "some_partial"
end
The partial is just html. _some_partial.html.erb could be
<br>Hi, this is the partial</br>
When I submit the form, I see the html response packet is received in the browser (with firebug's net logs), but the html doesn't show up anywhere. Where should the html be? How to render a partial html view from an action?
you are rendering a partial but not specifying where to render it.
in rails 2 you could do it with:
def some_action
# some logic
render :update do |page|
page.replace_html 'some_div_id', :partial => 'some_partial'
end
end
but in rails 3, above code is no longer valid.
see Unobtrusive Javascript
create a file named some_action.js.erb and write the code in it:
// update div with id some_div_id
$("#some_div_id").html("<%= escape_javascript(render :partial => 'some_partial') %>");
in controller
def some_action
# some logic
respond_to do |format|
format.js
end
end
I figured out how to send and display html. From theReq, just add :remote => true, "data-type" => "html" to the form and then in the javascript of the page, capture the returned html on ajaxSuccess to display it:
$('form#whatever').on('ajaxSuccess', function (event, data, status, xhr) {
$('div#target').html(data);
}
)

Make another controllers view a partial (Rails 3)

Have a post with comments. On post/show, when a user clicks the add comment button the server calls a javascript function that should add the new comment action as a partial:
render 'comments/new'
$("#newcomment").live("click",function() { $("#addcomment").load("<%= url_for :controller => 'comments', :action => 'new', :locals => {:parent_id => #post.parent_id} %>")
def new
#comment = Comment.new( :parent_id => params[:parent_id] )
render :partial => "form", :layout => false
end
new view:
render "form" # form is the add comment form
The problem is that the local variables are not passed and I can't add the comment (it wont call create)
render * never call an action in a controller, even render :action => 'edit'! It generates only the corresponding partial in every case. It may sometimes be confusing.
What you cand do to solve your probelm quickly is to call your partial via an ajax call.
In your views :
<div id="new_comment"></div>
In your controller :
render :update do
replace 'news_comment', partial => 'comments/new'
end
Hope this help.

How to use a partial layout with a collection? Rails

I am calling:
render #users, :layout => "homepage"
because I want to wrap the default partial for users (views/_user.html.erb) with a custom layout just for the homepage (views/users/_homepage.html.erb).
but, when I do this, I get the NoMethodError on the user.name method.
For some reason it seems like the user variable is not getting initialized properly inside the user partial.
It turns out after some test, the homepage partial is not even getting called, it is going straight to the user partial ....
This is not the solution I wanted, I believe there may actually be a way to make this work using just a call to render, but this is what gave me the correct output:
#users.each do |user|
render :partial => "users/user",
:layout => "users/homepage",
:locals => { :user => user }
end
Or is it that the :layout option only works when rendering a single resource and not a collection?
As of Sept. 2019, in Rails 6, this is how we are doing this:
<%= render partial: 'homepage_user_list_entry', collection: #users %>
With alias:
<%= render partial: 'homepage_user_list_entry', collection: #banned_users, as: :user %>
Hope this helps future searchers, and also me in the future.
Try adding :as => :user to render a partial from a view:
<%= render :collection => #users, :as => :user, :partial => 'users/user_short_form', %>
You should do something like
<%= render 'homepage', :collection => #users, :layout => 'homepage' %>
not sure about the :layout option, but you have to pass #users thro :collection
hope it helps!
Not sure if this is a newer addition to Rails, but in Rails 4.2.1 I can pass my collection to the partial argument of render:
render partial: #users, layout: "homepage"

Resources