Reputation: 1931
At the moment I have something like:
arr = [
:name,
:address,
cards_attributes: [
:last_name,
:first_name,
phones_attributes: [
:number,
:_destroy
],
emails_attributes: [
:number,
:_destroy
],
...
]
]
... and I want to turn it into something like:
arr = [
:id, # <- new!
:name,
:address,
cards_attributes: [
:id, # <- new!
:last_name,
:first_name,
phones_attributes: [
:id, # <- new!
:number,
:_destroy
],
emails_attributes: [
:id, # <- new!
:number,
:_destroy
],
...
]
]
I know I can add a new symbol to the first level with arr.push(:id)
but how do I add elements into the sub hashes?
Upvotes: 1
Views: 233
Reputation: 36101
def add_id(collection)
collection.unshift(:id) if collection.respond_to?(:unshift)
collection.each do |key, value|
add_id(key) if key.respond_to?(:each)
add_id(value) if value.respond_to?(:each)
end
end
EDIT: For the following update
"My question was actually more about how to elegantly access the sub hashes?"
We can use the same general idea. As you didn't specify an operation to be executed on the hashes, the method will expect a block:
def traverse(collection)
yield collection if collection.is_a? Hash
collection.each do |key, value|
traverse(key) if key.respond_to?(:each)
traverse(value) if value.respond_to?(:each)
end
end
traverse(arr) { |hash| puts hash }
Upvotes: 3
Reputation: 168071
This was an answer to the original question before the edit
arr.unshift(:id)
arr[-1][:cards_attributes].unshift(:id)
arr[-1][:cards_attributes][-1][:phones_attributes].unshift(:id)
or if you don't like using indices,
arr.unshift(:id)
arr.last[:cards_attributes].unshift(:id)
arr.last[:cards_attributes].last[:phones_attributes].unshift(:id)
or, you can also do:
arr.unshift(:id)
arr.dig(-1, :cards_attributes).unshift(:id)
arr.dig(-1, :cards_attributes, -1, :phones_attributes).unshift(:id)
Upvotes: 1