[英]Creating multiple records in ruby from a hash of arrays
我有一個由哈希內的數組哈希組成的響應。 我需要在ruby / rails中創建三個記錄(見下文)。
{
"first_name" => [John, Tom, Michael],
"last_name" => [Smith, Watts, Pit],
"email" => [John.smith@gmail.com, tom.watts@gmail.com, mike.pit@gmail.com]
}
id || first_name || last_name || email
----------------------------------------------
1 || John || Smith || john.smith@gmail.com
2 || Tom || Watts || tom.watts@gmail.com
3 || Michael || Pit || mike.pit@gmail.com
我在了解如何解決此問題時遇到困難。 任何幫助將不勝感激。
到目前為止,我有:
response.keys.each do |field_name|
response[field_name].each do |value|
puts "#{field_name} => #{value}"
User.create!(
first_name: value['first_name'],
last_name: value['last_name'],
email: value['email']
)
end
end
像這樣的方法怎么樣?
def create_records_from_responses!(responses)
items = responses.values.first.length
fields = responses.keys
users = []
# Don't process an empty set
return if items.zero?
# Wrap creation of User objects in a transaction
# If one fails, it rolls back all created records
# As per transaction documentation, you still have to manually
# handle the propagated error
# See: https://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html
# In this case we named the method with a `!` to indicate that it might raise
# an error. Whatever is calling this should rescue and handle the error
ActiveRecord::Base.transaction do
(0..items).each do |i|
attributes = {}
fields.each { |field| attributes[field] = responses[field][i] }
users << User.create!(attributes)
end
end
users
這有2個假設-
您的responses
哈希格式正確。 如果每個鍵都有不匹配的數組,則可能會出錯。 您應該事先驗證其形式
您正在創建的用戶數量並不多。 如您所見,它在每個循環中重建attributes
。 如果是10到20條記錄,這並不是什么大問題,但是如果您要處理更多的記錄,可以考慮對其進行優化。
只要保證數組的長度相同,並且順序不變,就可以執行以下操作:
data = {
first_name: ["John", "Tom", "Michael"],
last_name: ["Smith", "Watts","Pit"],
email: ["John.smith@gmail.com", "tom.watts@gmail.com", "mike.pit@gmail.com"]
}
0.upto(data[:first_name].length-1) do |i|
record = {
first_name: data[:first_name][i],
last_name: data[:last_name][i],
email: data[:email][i]
}
User.create!(record)
end
您也可以對.zip和.each_slice感到瘋狂,盡管我認為上面的內容更加簡單明了。
maxlen = data[:first_name].length
first_name_fields = Array.new(maxlen, 'first_name')
last_name_fields = Array.new(maxlen, 'last_name')
email_fields = Array.new(maxlen, 'email')
records = first_name_fields.zip(data[:first_name], last_name_fields, data[:last_name], email_fields, data[:email])
records.map!{|x| x.each_slice(2).to_a.to_h}
records.each{|record| User.create!(record)}
就這么簡單:
response.values.transpose.each { |record|
User.create!(data.keys.zip(record).to_h)
}
response.values
將給我們一個數組數組(每個字段的字段值數組),並且transpose
將其翻轉,因此我們有了記錄數組。 然后,對於每條記錄,只需添加字段名稱,進行哈希化並傳遞給#create!
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.