【Ruby on Rails】index_byを使用してオブジェクトをハッシュ化する
https://api.rubyonrails.org/classes/Enumerable.html#method-i-index_by
code:ruby
Status.all.index_by { |status| sutatus.name }
, # => {"tenure"=>#<Status id: 1, ...>, "leave_of_absence"=><Status id: 2, ...>, "separation_from_employment"=><Status id:3, ...>
https://blog.aiandrox.com/posts/tech/2021/03/31/
index_byがどんな場合に活用できるかあまりイメージが湧いていなかったけれど、N+1の解消に活用したのでまとめておく。
code:ruby
Message -< View >- User
message has_many views
user has_many views
code:ruby
class ViewController < ApplicationController
def index
@message = Message.find(params:id)
@view = View.includes(:user, :message).where(message_id: @message.id)
@users = User.all
end
end
code:ruby
- @users.each do |user|
- view = @view.where(user_id: user.id) # => N+1
each内でレコードの検索処理を書いたらコードの見直しサイン。
見直しのための一つの解決策としてindex_byで使用するレコードを事前にハッシュの形に加工する。
code:ruby
class MessagesController < ApplicationController
def index
@messages = Message.find(params:id)
@messages_assoc = View.includes(:user, :message).where(message_id: @message.id).index_by(&:user_id)
end
end
code:ruby
- @users.each do |user|
- view = @message_assocuser.id
index_byを利用することで発行されるクエリは各テーブル1回ごとになって、以下のように指定したkeyに対してオブジェクトをvalueとしたハッシュを作成することができる。
code:ruby
irb(main)> message_assoc
=>
{1=>
#<View:0x00...
id:25,
message_id:2,
user_id: 3
・
・
・
#ruby #rails