Rails 5 rendering partials and passing data

会有一股神秘感。 提交于 2019-12-11 05:34:56

问题


I'm having trouble getting traction on what the general ways data gets passed around from and is made available to partials.

For example:

I have a controller handing off an instance variable to a template that renders a partial:

static_pages_controller.rb:

def home
  @feed_items = current_user.feed
end

home.html.erb:

<%= render 'shared/feed' %>

_feed.html.erb:

<%= render @feed_items %>

Now, inside my User model is an instance method that reaching into the database to get her posts:

user.rb:

def feed
  Micropost.where("user_id = ?", id)
end

So somehow because Micropost.where(...) returns a collection of microposts is that how Rails knows to go from _feed.html.erb to another partial where the <li> is defined for how microposts want to be defined?

_micropost.html.erb:

<li id="micropost-<%= micropost.id %>">
  <%= link_to adorable_avatar_for(micropost.user, size: 50), micropost.user %>
</li>

And also is it just a convention that because I'm really handling a collection of microposts that Rails knows to give the micropost variable?


回答1:


Your questions are answered in the Ruby on Rails Guides on Layouts and Rendering. It's worth reading the information on partials that comes before the quoted passages below as well:

Every partial also has a local variable with the same name as the partial (minus the underscore). You can pass an object in to this local variable via the :object option:

<%= render partial: "customer", object: @new_customer %>

Within the customer partial, the customer variable will refer to @new_customer from the parent view. (Earlier the Guide instructs that to specify other options for render(), e.g. object:, you have to explicitly specify partial: and the name of the partial.)

If you have an instance of a model to render into a partial, you can use a shorthand syntax:

<%= render @customer %>

Assuming that the @customer instance variable contains an instance of the Customer model, this will use _customer.html.erb to render it and will pass the local variable customer into the partial which will refer to the @customer instance variable in the parent view.

3.4.5 Rendering Collections

Partials are very useful in rendering collections. When you pass a collection to a partial via the :collection option, the partial will be inserted once for each member in the collection:

index.html.erb:

<h1>Products</h1>
<%= render partial: "product", collection: @products %>

_product.html.erb:

<p>Product Name: <%= product.name %></p>

When a partial is called with a pluralized collection, then the individual instances of the partial have access to the member of the collection being rendered via a variable named after the partial. In this case, the partial is _product, and within the _product partial, you can refer to product to get the instance that is being rendered.

There is also a shorthand for this. Assuming @products is a collection of product instances, you can simply write this in the index.html.erb to produce the same result:

<h1>Products</h1>
<%= render @products %>

Rails determines the name of the partial to use by looking at the model name in the collection. In fact, you can even create a heterogeneous collection and render it this way, and Rails will choose the proper partial for each member of the collection:

index.html.erb:

<h1>Contacts</h1>
<%= render [customer1, employee1, customer2, employee2] %>

customers/_customer.html.erb:

<p>Customer: <%= customer.name %></p>

employees/_employee.html.erb:

<p>Employee: <%= employee.name %></p>

In this case, Rails will use the customer or employee partials as appropriate for each member of the collection.

In the event that the collection is empty, render will return nil, so it should be fairly simple to provide alternative content.

<h1>Products</h1>
<%= render(@products) || "There are no products available." %>


来源:https://stackoverflow.com/questions/40955973/rails-5-rendering-partials-and-passing-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!