Rails 5 渲染部分和传递数据
Rails 5 rendering partials and passing data
我无法理解数据传递的一般方式以及部分数据可用的方式。
例如:
我有一个控制器将实例变量传递给呈现部分的模板:
static_pages_controller.rb:
def home
@feed_items = current_user.feed
end
home.html.erb:
<%= render 'shared/feed' %>
_feed.html.erb:
<%= render @feed_items %>
现在,在我的 User 模型中有一个实例方法可以访问数据库以获取她的帖子:
user.rb:
def feed
Micropost.where("user_id = ?", id)
end
所以不知何故,因为 Micropost.where(...)
returns 微博的集合是 Rails 如何知道从 _feed.html.erb
到 <li>
所在的另一个部分微博要怎么定义?
_micropost.html.erb:
<li id="micropost-<%= micropost.id %>">
<%= link_to adorable_avatar_for(micropost.user, size: 50), micropost.user %>
</li>
这是否只是一个约定,因为我实际上正在处理 Rails 知道的 microposts
的集合,所以要给 micropost
变量?
您的问题已在 Ruby on Rails Guides on Layouts and Rendering 中得到解答。下面引用的段落之前的部分信息也值得一读:
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." %>
我无法理解数据传递的一般方式以及部分数据可用的方式。
例如:
我有一个控制器将实例变量传递给呈现部分的模板:
static_pages_controller.rb:
def home
@feed_items = current_user.feed
end
home.html.erb:
<%= render 'shared/feed' %>
_feed.html.erb:
<%= render @feed_items %>
现在,在我的 User 模型中有一个实例方法可以访问数据库以获取她的帖子:
user.rb:
def feed
Micropost.where("user_id = ?", id)
end
所以不知何故,因为 Micropost.where(...)
returns 微博的集合是 Rails 如何知道从 _feed.html.erb
到 <li>
所在的另一个部分微博要怎么定义?
_micropost.html.erb:
<li id="micropost-<%= micropost.id %>">
<%= link_to adorable_avatar_for(micropost.user, size: 50), micropost.user %>
</li>
这是否只是一个约定,因为我实际上正在处理 Rails 知道的 microposts
的集合,所以要给 micropost
变量?
您的问题已在 Ruby on Rails Guides on Layouts and Rendering 中得到解答。下面引用的段落之前的部分信息也值得一读:
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." %>