简体   繁体   中英

How can I convert this group_by statement so that it works off the DB instead of Ruby?

I'm building a yearly archive for a site and I have it working but I'm using group_by. This specific site will end up having thousands of posts eventually and I would like to move the grouping to the database but I'm not really sure how to convert it to an active record query.

I'm using active record and rails 4, here's what I have so far:

In the controller:

@posts_by_year = @posts.group_by { |post| post.published_at.year }

In the view:

  <% @posts_by_year.each do |year, post| %>
    <li><%= "#{year} - #{pluralize post.count, 'post'}" %></li>
  <% end %> 

Produces a list that looks like:

2013 (5 posts)
2012 (2 posts)
2010 (1 post)

How can I replicate this exact functionality but have the DB do the grouping instead and do you think it's worth making the switch if you expect to have 2,000-3,000 posts per year? Lastly will the active record implementation be different if I use mysql or postgres?

In the controller (assume from the tags that your are using mysql)

@posts_by_year = @posts.select("YEAR(published_at) AS year, COUNT(id) AS counter").group("YEAR(published_at)")

In the view

<% @posts_by_year.each do |post| %>
  <li><%= "#{post.year} - #{pluralize post.counter, 'post'}" %></li>
<% end %>

You need to use a function to get the year, and it will depend on your DB; For example, for PostgreSQL, you can use EXTRACT :

Post.group('extract(year from published_at)').count
# => { 2013 => 5, 2012 => 2, 2012 => 1 } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM