窓際BLOG

プログラミングの学習メモや書籍の感想等を公開していきます。

RubyonRails:ActiveRecord::Relationをto_aすると色々とはかどるかも知れない件

最近ActiveRecord::Relationをto_aすると色々とはかどるかも知れないという知見を得たのでメモしておきますφ(..)

whereを使って取得した結果(ActiveRecord::Relation)をselectとか使って結果から特定の値を持つレコードを取ってこようとするとやDBアクセスが走っちゃうとかあると思うんですけども、そういうときはto_aして配列に変換してあげるとDBアクセス発生させずに操作が出来るので便利という話しです。

下記は例ですが、カテゴリ別に投稿されたブログのタイトルの一覧を取得しようとした場合、view内で@blogsをカテゴリで絞込を行おうとするとDBアクセスが発生し、パフォーマンスが落ちてしまいます。

controller

# controller
def index
  @blogs = Blog.where(user_id: current_user.id)
  @category = Category.all
end

view

<% @category.each do |c| %>
  <% # ここのwhereでDBアクセスが入ってしまう。。。 %>  
  <% blogs = @blogs.where(category_id: c.id)%>
  <h3><%= c.name %></h3>
  <% blogs.each do |blog| %>
    <p>blog.title</p>
  <% end %>
<% end %>

しかし、to_aしてあげるとArrayのメソッドが使えるようになり下記のように書き直すことが出来ます!
配列の操作なのでDBアクセスは発生しませんし、group_byを使ってカテゴリをkeyとしたhashに分割することで綺麗に処理が書けますね\(^o^)/

controller

# controller
def index
  @blogs = Blog.where(user_id: current_user.id)
               .to_a.group_by{ |blog| blog.category_id }
  @category = Category.all
end

view

<% @category.each do |c| %>
  <h3><%= c.name %></h3>
  <% blogs[c.id].each do |blog| %>
    <p>blog.title</p>
  <% end %>
<% end %>

以上です(・∀・)