Add a hash pluck method?

The regular AR pluck method returns the values only, for instance: Student.pluck(:firstname) => [“John”, “Mike”, “Simon”]

It’d be a nice feature to have a version which returns a hashes with the column names as keys: [{ firstname: “John”}, { firstname: “Mike” }, { firstname: “Simon” }]

I know this can (almost) be achieved with (it forces you to have an id attribute), but this involves instantiating lots of AR objects, which loses the benefit of pluck.

An example implementation would be:

def self.hash_pluck(*keys)
pluck(*keys).map{ |vals| Hash[] }


In some (probably bad) benchmarks I made comparing this to the select alternative, the select method was ~3.4x slower.

Benchmark.ips do |x|“hash_pluck”) { Student.hash_pluck(:firstname) }“select”) { }!

Calculating -------------------------------------
select 6.000 i/100ms
hash_pluck 24.000 i/100ms

What is the benefit of this method?

You can pluck(:firstname).map { |e| { firstname: e } } if you really wanted that. Why are you plucking and wanting it to be a hash?

The proposed method has more benefit when plucking multiple columns. Of course, you can still do pluck(:first, :last, :dob).map {|e| {first: e[0], last: e[1], dob: e[2]} }, but I guess that’s a little cumbersome and smelly. I’m not arguing the benefit – small benefit IMO – is worth the cost of adding and maintaining for years, but I do see its convenience.


I would definitely use this, given we don’t currently have many good options for querying against the database and getting non-ActiveRecord objects back.

I often want a fast way to serialize stuff as JSON (ie. without instantiating AR objects and then turning them back into hashes), and doing this using select_values is pretty cumbersome.

For example: render json: { tasks: current_user.tasks.hash_pluck(:id, :name, :completed) }

That said, I’d probably favour a more general way to query the database and get back arrays/hashes over something like hash_pluck, which would only handle very simple cases.

The pluck_to_hash gem ( encapsulates this functionality, if you're interested.