Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for Rails' Partial Features You (didn't) Know
Rails Designer
Rails Designer

Posted on • Originally published atrailsdesigner.com

     

Rails' Partial Features You (didn't) Know

This article was originally published onRails Designer


Partials have been an integral part of Rails. They are conceptually simple to understand, but they pack quite a few smart and lesser known features you might not know about. Let's look at all of them!

Basic rendering

Let's look at the basics of rendering a partial.

<%=renderpartial:"application/navigation"%>
Enter fullscreen modeExit fullscreen mode

This will render the partialapp/views/application/_navigation.html.erb. The filename starts with an underscore, but is references without one.

You can also omit thepartial keyword.

<%=render"application/navigation"%>
Enter fullscreen modeExit fullscreen mode

So far nothing you didn't know already, I assume.

Local Variables

You can pass variables like so.

<%=renderpartial:"user",locals:{user:@user}%>
Enter fullscreen modeExit fullscreen mode

Again, this short-hand can also be used:

<%=render"user",user:@user%>
Enter fullscreen modeExit fullscreen mode

Or if you follow conventions from a to z, you could write this:

<%=render@user%>
Enter fullscreen modeExit fullscreen mode

This assumes a few things:

  • @user is present
  • a partial_user.html.erb inapp/view/users.

Quite a bit cleaner, right? So when does one use the short-hand version and when not? Typically you can use the short-hand version, especially when you are only passing 1 or 2 variables. But you can also pass other arguments; then it's required to use the longer syntax. Like this example:

<%=renderpartial:"user",locals:{admin:@admin},as: :user%>
Enter fullscreen modeExit fullscreen mode

Explicit local variables

Introduced in Rails 7.2. You can set explicit local variables to clearly tells which variables are required.

<%# locals: (name:) -%><%=name%>
Enter fullscreen modeExit fullscreen mode

You can also set a default value. So that if the user has no name set, it renders "Stranger".

<%# locals: (name: "Stranger") -%><%=name%>
Enter fullscreen modeExit fullscreen mode

Local assigns

You can also use “implicit local variables”. Assume the aboveuser_details is used in an admin view.

<div><p><%=name%></p><%local_assigns[:admin?]%><dl><dt>      Created at:</dt><dd><%=user.created_at%></dd></dl><%end%></div>
Enter fullscreen modeExit fullscreen mode

You can render the partial like so:

<%=render"user",user:@user,name:"Cam",admin?:true%>
Enter fullscreen modeExit fullscreen mode

Or omit theadmin?: true in non-admin views:

<%=render"user",user:@user,name:"Cam"%>
Enter fullscreen modeExit fullscreen mode

This is useful, because without thelocal_assigns, rendering would fail.

Layouts for partials

You can also wrap a partial in a “layout”. This is not to be confused with view layouts stored inapp/views/layouts.

<%=renderpartial:"user",layout:"shared/admin"%>
Enter fullscreen modeExit fullscreen mode

The admin “layout” is stored atapp/views/shared/_admin.html.erb and could look like this:

<divclass="admin"><%=yield%></div>
Enter fullscreen modeExit fullscreen mode

Render collection

If you want to render a collection of users, you can write the following, for example inapp/views/users/index.html.erb:

<%=renderpartial:"user",collection:@users%>
Enter fullscreen modeExit fullscreen mode

Or its shorthand variant:

<%=render@users%>
Enter fullscreen modeExit fullscreen mode

This automatically looks up the_user.html.erb partial inapp/views/users, assuming@users is a collection ofUser's.

It doesn't have to a collection of one and the same Resource though, e.g.User. This too works:

<%=render[User.first,Admin.first,Customer.first,User.second]%>
Enter fullscreen modeExit fullscreen mode

This is assuming you have those resources, and each has their respective partial, e.g. _user.html.erb, _admin.html.erband_customer.html.erb.

Empty State

If the collection, e.g.@users is empty,render returnsnil. So if you want to render an empty state, that is simple.

<%=render(@users)||"No users yet…"%>
Enter fullscreen modeExit fullscreen mode

Local variables

You can change the the local variable with a collection too.

<%=renderpartial:"user",collection:@users,as: :customer%>
Enter fullscreen modeExit fullscreen mode

In the_user.html.erb partial, you can now usecustomer.id (or whatever other attribute is available).

You also pass other variables:

<%=renderpartial:"user",collection:@users,locals:{admin?:true}%>
Enter fullscreen modeExit fullscreen mode

Counter variables

You can render a counter too:<%%= user_counter %>. The name, the part before the underscore, is derived from the partial name. So**customer.html.erb* would be*<%%= customer_counter %>.

Layout for collections

Similarly to resource partials, you can also pass collections partials thelayout option.

<%=renderpartial:@users,layout:"users/wrapper"%>
Enter fullscreen modeExit fullscreen mode

Then inapp/views/users/_wrapper.html.erb, you could have something like this:

<ulid="users"><%=yield%></ul>
Enter fullscreen modeExit fullscreen mode

Spacer template

There is one last option for collection which isspacer templates. It will be inserted between each instance. Use it like so:

<%=renderpartial:@users,spacer_template:"user/divider"%>
Enter fullscreen modeExit fullscreen mode

This will load the partialapp/views/users/_divider.html.erb.

Bonus: Make partials look like components

If you have usedViewComponent, but can't use them in your current project for whatever reason, here's a way you make your partials quack a bit more like ViewComponent.

Create your components inapp/view/components. For example a_card.html.erb.

<sectionclass="card"><h4class="card__header"><%=title%></h4><divclass="card__body"><%=yield%></div></section>
Enter fullscreen modeExit fullscreen mode

Then in your view use it like this:

<%=renderlayout:"components/card",locals:{title:"User Profile"}do%><p>Just some text for this user</p><%end%>
Enter fullscreen modeExit fullscreen mode

But you probably want a helper to abstract some of that boilerplate away.

# app/helpers/components_helper.rbmodule ComponentsHelper  def component(name, **,&)    render layout: "components/#{name}", locals: **,&  endend
Enter fullscreen modeExit fullscreen mode

Now you render it like this:

<%=component"card",title:"User Profile"do%><p>Just some text for this user</p><%end%>
Enter fullscreen modeExit fullscreen mode

Pair that with theExplicit local variables and you got a pretty solid component-like set up without any dependencies.

And that are all the things you (didn't) know about Rails' partials.

Top comments(1)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
railsdesigner profile image
Rails Designer
I help teams around the world make their Rails apps a bit nicer to maintain and look at. 🎨 Also kickstart SaaS' in a month. 👷 And built a Rails UI Components library, used by 1000+ developers. 🚀

Quite surprising this amount of features, isn't it? Which one was new to you?

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

I help teams around the world make their Rails apps a bit nicer to maintain and look at. 🎨 Also kickstart SaaS' in a month. 👷 And built a Rails UI Components library, used by 1000+ developers. 🚀
  • Location
    Amsterdam, The Netherlands
  • Joined

More fromRails Designer

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp