by April 10, 2015

PostgreSQL array type support makes it easy to have an array of tags on a Rails model.

1
2
3
create_table :posts do |t|
  t.string :tags, array: true, default: []
end

Now that you're storing some tags on your Post (hand-waving...), you might want to grab an array of unique tags entered on posts.

You might start down the path of selecting the post tags, then collecting them, something we see often in Rails code.

Post.select('tags').collect(&:tags).flatten.uniq

You have an array of the tags, but that's kinda ugly. There's a lot of Ruby manipulation going on after the tags are retrieved. The pluck method can help with this, by giving us just the attributes we're looking for.

Post.pluck('tags').flatten.uniq

Same result as before, but much nicer. We still have that pesky flatten.uniq hanging off the end, though. PostgreSQL has an array function called unnest that will give us the same result as our Ruby flatten method and distinct will ensure they're unique.

Post.pluck('distinct unnest(tags)')

There we go, offload some of those operations onto the database. This should be much more efficient than Ruby, so we ran some simple benchmarks against 10000 posts, with 20382 tags (183 unique).

1
2
3
4
         user     system      total        real

old: 0.240000   0.000000   0.240000 (  0.245174)
new: 0.000000   0.000000   0.000000 (  0.010110)

Looks much better!

Curtis Miller

Curtis Miller

Managing Partner

Startup junkie, Rubyist and gamer. Loves to brainstorm about new ideas.

Need help with your project?

We specialize in Ruby on Rails and JavaScript projects. Code audits, maintenance and feature development on existing apps, or new application development. We've got you covered.

Get in touch!