In my patient show view i have a part that refers to a partial
<h2>Anamnesen</h2>
<%= render #patient.anamneses %>
So i also created an partial in views/anamneses/ called _anamnese.html.erb
<p>
<b>Beschreibung:</b>
<%= anamnese.beschreibung %>
</p>
Now, my problem is that only Beschreibung: can be seen, the <%= anamnese.beschreibung %> is somehow blank! So maybe someones gues what i made wrong!
You need to pass variables explicitly by locals option for the partials to know it.
In the first template
render partial: 'anamneses/anamneses', locals: {anamneses: #patient.anamneses}
Related
I have a collection and want to iterate and render a partial:
<% #programs.each do |program| %>
<%= render "program", link: program_path(program) %>
<% end %>
For each rendering, I will pass a parameter called link. And it varies based on different situation.
program_path(program)
admin_program_path(program)
program.external_link
However, it will spend a huge time to render every partial, so it's a N+1 problem. I also tried to render collections but I don't know how to pass the parameter.
Does anyone know a better way to do it? Or shall I give up partial and put those code to every page which rendering the partial?
Cheers
You could use:
<%= render #programs %>
And create:
views/programs/_programs.html.erb
Then you choose the link with a condition in the partial.
I have a resource called Exercises in my application. I currently have a partial called _exercise.html.erb that I use to render them. I have an outlying case where I'd like to render them in a much different way. Can I make another partial for exercises that has this other format and still be able to use <%= render #exercises %>?
If not what is the best approach? Should I out a variable in the controller that tells the partial which layout to use, this would have both layout in one file and one if to decide. Or is there some better way?
If you'd like to use business logic to determine when to show what partial for your #exercises collection you should use the to_partial_path method in the Exercise model to define that. See #4 in this post: http://blog.plataformatec.com.br/2012/01/my-five-favorite-hidden-features-in-rails-3-2/
Or, if this is more of a view-related decision (i.e. one view will always use the regular _exercises.html.erb and another view would always use e.g. _alternate_exercises.html.erb) then you can specify as such:
<%= render partial: 'alternate_exercises', collection: #exercises, as: :exercise %>
This will render the _alternate_exercises.html.erb partial once for each item in #execrises passing the item in to the partial via a local_assign called exercise.
In this case, I suppose you have two options:
1) Put the conditional code inside of _exercises.html.erb
eg.
<% if #exercise.meets_some_condition %>
you see this stuff
<% else %>
you see other stuff
<% end %>
This way, you can still make use of <%= render #exercises %>
2) Otherwise, your other option is to have separate partials and render them outside.
eg.
<% #exercises.each do |exercise| %>
<% if exercise.meets_some_condition %>
<%= render "exercises/some_condition_exercise" %>
<% else %>
<%= render "exercises/exercise" %>
<% end %>
<% end %>
This is the best approach for rendering partial. You can wrap that partial with if else statement in your code. Here is my example
rendering with form called _victim.html.erb
<%= render :partial => "victim", :locals => {:f => f }%>
rendering without form
<%= render :partial => "victim"%>
when I render an partial for my model I'm using:
<%= partial #my_model %>
Automatically it looks for the file ..view/my_models/_my_model.html.erb
I really like this notation because it feels the right way!
My Problem:
Now I want a notation to automatically look up for the edit partial.
Is there a way? Until now I used
<%= partial 'edit' %>
This is ok, but I have a lot of subclasses for my model and I liked the way that it automatically looks up in the right subclasses view folder for the template.
Until know I have to look for the class for my model and then call
<% if #my_model.class == FirstSubClass %>
<%= partial 'firstsubclasses/_edit.html.erb' %>
<% elsif #my_model.class == SecondSubClass %>
<%= partial 'secondsubclasses/_edit.html.erb' %>
<% end %>
I prefer one line :) Any ideas?
Try:
<%= partial '#{#my_model.class.name.tableize}/_edit.html.erb' %>
tableize is a method of ActiveSupport::Inflector, which includes some other cool naming manipulation methods.
I have a partial that I'm rendering twice on the same page, but in two different locations (one is shown during standard layout, one is shown during mobile/tablet layout).
The partial is rendered exactly the same in both places, so I'd like to speed it up by storing it as a variable if possible; the partial makes an API call each time, and the 2nd call is completely unnecessary since it's a duplicate of the first API call.
Is there any way to store the HTML from the returned partial as a variable and then use that for both renders?
Edit: I'm hoping to do this without caching, as it is a very simple need and I'm looking to keep the codebase lean and readable. Is it possible to store the partial as a string variable and then reference that twice?
<% content_for :example do %>
<%= render :your_partial %>
<%end%>
then call <%= yield :example %> or <%= content_for :example %> wherever you want your partial called.
One option would be to use fragment caching. After you wrap the partial with a cache block, the second call should show the cached version of the first. For example:
<% cache do %>
<%= render(:partial => 'my_partial') %>
<% end %>
... later in the same view ...
<% cache do %>
<%= render(:partial => 'my_partial') %>
<% end %>
To store the result of the render to a string, you could try the render_to_string method of AbstractController. The arguments are the same as for render.
partial_string = render_to_string(:partial => 'my_partial')
I'm adding an answer to this old question because it topped Google for a search I just made.
There's another way to do this now (for quite a while), the capture helper.
<% reuse_my_partial = capture do %>
<%= render partial: "your_partial" %>
<% end %>
<div class="visible-on-desktop"
<%= reuse_my_partial %>
</div>
<div class="visible-on-mobile"
<%= reuse_my_partial %>
</div>
This is simpler and slightly safer than using content_for because there is no global storage involved that something else might modify.
The rails docs linked to use instance #vars instead of local vars because they want it to be available to their layout template. That's a detail you do not need to worry about, because you're using it in the same template file.
Here's the call in the application.html.erb file:
<%= render :partial => 'tasks/_new' %>
Here's the partial being rendered (_new.html.erb):
<% form_for #task do |f| -%>
<%= f.text_field :body %>
<%= submit_tag "Submit" %>
<% end -%>
Here's the method in the 'tasks' controller:
def new
#task = Task.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #task }
end
end
Here's the error message I keep getting:
Missing template tasks/__new.erb in view path app/views
And it says the error is in this line:
<%= link_to "tasks", tasks_path %> <%= render :partial => 'tasks/_new' %>
The file is in the right directory. The weird thing is that there's an
extra _ in the file name, in the error. When I give in and rename the
partial to __new.erb, here's the error I get:
Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
And it says the error is in this line:
<% form_for #task do |f| -%>
I had also tried without the _ in the code, as Petros suggested, but it returns the same error as above, Called id for nil….
What's going on?
You don't need the _ in your code. It should be:
<%= render :partial => 'tasks/new' %>
The first error is because you don't need to put the _ inside the :partial parameter. Rails takes care of that. That's why you get double __ because Rails will put one for you.
The second error is your real problem. The error suggests that #task is nil. This is true because the partial only knows what the container view knows, and your view in that particular moment hasn't called the action from the proper controller. As you (Baby Diego) already found out and indicated in one of your comments below, you needed to create an instance of a Task in your partial. I don't know if there is a more elegant solution, but maybe someone can suggest something better in the future.
Thanks to MattMcKnight for informing us that the partial itself does only know what the container view knows.
Petros correctly identified the first issue- you don't need the underscore in the partial call.
The second thing to know about partials is that they don't call the controller method, they just reference the view. Thus, you need to setup the #task object in every action that uses that partial, or just call Task.new in the partial. When I have a partial in a layout in similar situations, I usually load it with JavaScript so that I can call the action.
If the partial needs to know about a variable in the calling erb file, you can pass it like this:
<%= render partial: "tasks/new", locals: { task: #task } %>
And in file app/views/tasks/_new.html.erb, refer to the variable like this:
<% form_for task do |f| %>
<%= f.text_field :body %>
<%= submit_tag "Submit" %>
<% end %>
That is, without the #. (The code a: b is just a more convenient form of :a => b.)
I wonder, though, why do you want to use partials in file application.html.erb? I'm assuming that you mean the Ruby-generated file app/views/layouts/application.html.erb, which is supposed to be used as a layout file containing elements common to all your application's pages, not for business logic. Perhaps the file you need to call the partial from is app/views/tasks/index.html.erb?