Although Ruby / Rails doesn't yet support an equivalent to the ES6 shorthand syntax for hashes, there are a few handy idioms already that often come in handy.
Ruby
Consider the following method:
def test_splat(a:, b:, c:)
[a, b, c].inspect
end
test_splat(a: 4, b: 5, c: 6)
yields "[4, 5, 6]"
Although if you already have a hash such as hash = { a: 1, b: 2, c: 3 }
, you can simply call it like this:
test_splat(hash)
which yields "[1, 2, 3]"
Further
If you have a sub_hash, you can use it alongside other kwargs using the kwarg splat operator **
. For example if you have sub_hash = { a: 1, b: 2 }
, calling:
test_splat(sub_hash)
yields ArgumentError: missing keyword: c
and calling:
test_splat(sub_hash, c: 3)
yields ArgumentError: wrong number of arguments (given 1, expected 0)
but using the splat operator **
, you can do splat the sub_hash
arg:
test_splat(**sub_hash, c: 3)
which yields "[1, 2, 3]"
For more reading see https://www.justinweiss.com/articles/fun-with-keyword-arguments/
Rails
The above plus a few extra methods can come in handy for Rails users, particularly in controllers when params are passed in.
Suppose you have an ActionController::Parameters
object with more attributes than you need and you want a subset. E.g: { a: 1, b: 2, d: 4 }
. The slice
method on Hash
is very handy here.
First, permit your params:
permitted_params = params.permit(:a, :b, :d).to_h.symbolize_keys
.
We add .to_h.symbolize_keys
because ActionController::Parameters
doesn't support symbolize_keys
, and kwargs require the args' keys to be symbols, not strings. So the .to_h
converts it to an ActiveSupport::HashWithIndifferentAccess
, and the symbolize_keys
converts the hash's keys from strings to symbols.
Now, calling:
test_splat(**permitted_params, c: 3)
will yield ArgumentError: unknown keyword: d
as expected since d
isn't a kwarg for the test_splat
method. Although using slice achieves what we want here:
test_splat(**permitted_params.slice(:a, :b), c: 3)
yields "[1, 2, 3]"