34
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Railsのpartialでcollectionを渡すときにはindexの変数が自動的に作られる

Last updated at Posted at 2018-08-17

オブジェクトの配列を元にパーシャルを表示するときに、それがいま何番目かをカウントしたいときがあると思います。

Railsにおいて配列からパーシャルを表示したい場合には、= render 'partial_name', collection: @objectsを使う方がよいとされます。1
しかし、この方法ではindexの変数を渡すことができないように見えます。

そのため、collection:を使わずにeachを回してrenderを実行したくなりますが、その必要はありません。

実は、Railsのrender partial: ..., collection: ...を実行するとカウント変数が作られていて、表示したpartialの数をカウントしてくれています。2

そのカウント変数は、パーシャル内で#{variable_name}_counterという名前で作成されています。
(適宜、variable_nameを利用している変数に読み替えてください。)

コード例

users/index.html.slim
ul.user-list
  = render partial: 'shared/user', collection: @users
shared/users.html.slim
/ この変数名はパーシャルの名前ではなく、`collection:`に渡した変数名を元に作成されます。
/ そして、indexは0からはじまるので注意
li.user-list-item
  | (#{user_counter + 1}) #{user.full_name} # => (1) 田中 太郎

おまけ

要素が複数の場合はカウントを表示したいけれど、一つの場合は表示したくない、という状況があったりしますよね。
カウント変数はパーシャルが一つのときには定義されないため、以下のように実装するといいんじゃないかなと思います。

shared/_opening_job_position.html.slim
ul.job-list
  - if @opening_job_postions.one?
    = render partial: 'shared/opening_job_position', locals: { : @opening_job_positions.first }
  - else
    = render partial: 'shared/opening_job_position', collection: @opening_job_positions
shared/_opening_job_position.html.slim
li.job-list-item
  / 生成されるのは変数であるため、Object#tryでチェックすることはできないので注意。
  - if defined?(opening_job_position_counter)
    | (#{opening_job_position_counter + 1})
  | #{opening_job_position.name}

「こうした方がよいでしょ」みたいなツッコミ・提案をお待ちしております。

  1. eachを使って= render 'partial_name', locals: { object: @object }をループするのは、パフォーマンスが悪くなるためできる限り避けたほうが良いです。

  2. render partial: ..., collection: ...というふうにcollection:を渡した場合にのみにカウント変数が作られます。

34
25
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?