Home > OS >  Rails: Map array with values to model
Rails: Map array with values to model

Time:12-24

I have a problem. In my application I created the following migration for my model:

create_table(:calculation, primary_key: [:name, :value1]) do |t|
    t.string :name 
    t.bigint :value1
    t.decimal :value2
    t.decimal :value3
    t.decimal :value4
    t.timestamps
end

From the API that I am connecting to, I get a response that looks like this:

[
    [
        44812342,          // value1
        "723.21000000",    // value2
        "723.21000000",    // value3
        "0",               // UNNESSECARY VALUE (SKIP THIS ONE)
        "723.21000000",    // value4
    ],
    [
        44812342,          // value1
        "723.21000000",    // value2
        "723.21000000",    // value3
        "0",               // UNNESSECARY VALUE (SKIP THIS ONE)
        "723.21000000",    // value4
    ]
]

Now I want to write a job which at the end writes all the received calculations to my postgres DB using bulk insert. Performance is really important, so I thought I should map it first to rails models and then call the insert_all and pass the array with all the models. The problem I am having is that the result does not contain any hashes. I thought of using something like this:

name = 'MyName'
calculationModels = calculationArrays.map do |calculation|
    Calculation.new(
        name: name, 
        value1: calculation[0], 
        value2: calculation[1], 
        value3: calculation[2], 
        value4: calculation[4]
    )
end

Calculation.insert_all(calculationModels)

but I am not sure if this is fast to use, because in production it will do this for like over a million calculations, so my question is.. What is the fastest way to get these arrays into my database?

CodePudding user response:

When you response from the API looks like this:

nested_values = [
  [44812342, "723.21000000", "723.21000000", "0", "723.21000000"],
  [44812342, "723.21000000", "723.21000000", "0", "723.21000000"]
]

then you can just input records into your database like this:

nested_values.each do |values|
  Calculation.create!(
    name: 'A NAME',
    value1: values[0],
    value2: values[1],
    value3: values[2],
    value4: values[4],
  )
end

Or you can use insert_all like this:

Calculation.insert_all(
  nested_values.map { |values|
    { 
      name: 'A NAME',
      value1: values[0],
      value2: values[1],
      value3: values[2],
      value4: values[4] 
    }
  }
)

Note that you will need to set a name in both cases, because you defined that column to be part of the primary key.

  • Related