Rails: Should Partials Be Aware of Instance Variables

Rails: Should partials be aware of instance variables?

In recent versions of Rails it is quite a bit easier to render partials and pass locals to them. Instead of this.

<%= render :partial => 'form', :locals => { :item => @item } %>

You can do this.

<%= render 'form', :item => @item %>

I don't do this in the Nifty Scaffold generator to keep backwards compatibility, but I'll change this in a future release.

As for whether it's acceptable to use instance variables in partials. I think it is. In all practicality, what is the downside? Certainly things can get out of hand if you aren't consistent, but I like to apply these guidelines.

  1. Never create an instance variable just to share it between partials. Usually this means you will only be sharing the controller resource object.

  2. If the partial is the same name as the resource, pass it as a local with <%= render @item %>.

  3. If the partial will be shared across multiple controllers then only use locals.

This is what works well for me anyway.

Bonus tip: if you find yourself passing in a lot of locals into a partial and you want some of them to be optional, create a helper method which renders the partial. Then always go through the helper method so you can make a clean interface with optional args for rendering the partial.

Avoid using instance variables in partials views

Yes. It is located in a partial file

That's what the warning/error tells you: don't use instance variables in partial files. Rather, use local variables. Example:

Your partial render looks something like this:

= render 'my_partial'

Change it like this to pass all variables explicitly:

= render 'my_partial', productrecords: @productrecords, clone_record: @clone_record

And your partial will use the locals now:

= f.association :product, :collection => Category.products,:include_blank => "Select Product",
:label => "* Product",
:selected =>productrecords.product_id ? productrecords.product_id : clone_record.product_id

how to test partial with instance variables

It looks like you're using rspec. In that case, any instance variables you define during your test will be available for your views (regardless if it's a partial or not).

describe "users/_messages" do
before(:each) do
# This is available in your view.
@items = []
end

it "renders without error when @items is empty" do
# Will pass, @items is available
expect { render }.to_not raise_error
end

it "shows a count of how many messages there are" do
# You can modify it before rendering
@items << Message.new
render

expect(rendered).to have_content "You have 1 message"
end
end

Passing instance variables in nested partials in Rails?

You are passing ref as argument to the partial in home.html.erb, so in _product_table.html.erb you should use it similarly to item, not as instance variable:

<% @items.each do |item|%>
<%= render "own/product", :item => item, :ref => ref %>
<% end %>

Should you only use local variables in a partial?

You're on a roll today! :-)

You can pass variables into the partial as :locals to keep this all nice and clean. For example,

render :partial => 'my_partial', :locals => { :some_variable => some_variable, :some_important_value => 'an important point!' }

These variables are then available in the partial view:

<%= some_variable %>
<%= some_important_value %>

However, there is nothing specifically wrong with using instance variables in your partials.

How to pass an instance variable into a view partial?

Assign whatever variable you want to posts

<%= render "posts", posts: @featured_posts %>

And now loop over posts in the partial. You will have @featured_posts in posts variable now

<% posts.each do |post| %>
<div class="col-sm-4">
<div class="thumbnail">
<img src="#">
<div class="caption">
<h4><%= link_to post.title, post %></h4>
<%= post.text.truncate_words(60, omission: '...') %>
<a href="#" class="btn btn-default btn-xs" role="button">Button</a>
</div>
</div>
</div>
<% end %>

For @recommended_posts render the same partial but pass @recommended_posts to posts

<%= render "posts", posts: @recommended_posts %>

Rails: How to pass instance variables from a controller to render partial

You should do like this, removing @. You are passing it to local variable article so you could access it with article not @article:

<% if article.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(article.errors.count, "error") %> prohibited this
article from being saved:
</h2>
<ul>
<% article.errors.full_messeages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>

<p>
<%= f.label :title %><br />
<%= f.text_field :title %>
</p>

<p>
<%= f.label :text %><br />
<%= f.text_area :text %>
</p>

<p>
<%= f.submit %>
</p>

For more info, please take a look at passing-local-variables



Related Topics



Leave a reply



Submit