Sorry for my bad english and for any stupid error, but I'm learning Ruby since few month. I'm trying to read from a .xlsx file usign roo gem and after I would store my rows in the database, in a already existing model. Here there is my Court model:
class Court < ApplicationRecord
belongs_to :type
validates :type_id, presence: true
validates :name, presence: true
validates :email, presence: true, uniqueness: true
validates :responsible, presence: true
validates :address, presence: true
validates :telephone, presence: true, format: { with: /\A([0-9]*\-?\ ?\/?[0-9]*)\Z/ }
geocoded_by :address
after_validation :geocode, :if => :address_changed?
end
# == Schema Information
#
# Table name: courts
#
# id :integer not null, primary key
# type_id :integer
# name :string(255)
# email :string(255)
# email_type :string(255)
# responsible :string(255)
# address :string(255)
# telephone :string(255)
# latitude :decimal
# longitude :decimal
# created_at :datetime not null
# updated_at :datetime not null
#
and I created a task as follow, excel.rake, to read with roo all the file:
namespace :excel do
desc "Import Courts from Excel"
task import_courts: :environment do
xlsx = Roo::Excelx.new(Rails.root.join('app', 'assets', 'excel', 'Tribunali.xlsx'))
xlsx.parse(headers: true) do |hash|
puts hash.inspect # Array of Excelx::Cell objects
@court = Court.new
@court.hash
@court.save
end
end
end
In the file I have the same headers of the model, indeed when I launch the task I obtain the following output:
{"Tipo"=>"Tipo", "Nome"=>"Nome", "Indirizzo e-mail"=>"Indirizzo e-mail", "Tipo email"=>"Tipo email", "Responsabile"=>"Responsabile", "Indirizzo"=>"Indirizzo", "Numero Telefonico"=>"Numero Telefonico"}
{"Tipo"=>"AMM", "Nome"=>"Ministero della Giustizia", "Indirizzo e-mail"=>"[email protected]", "Tipo email"=>"PEC", "Responsabile"=>"Alfonso Bonafede", "Indirizzo"=>"Via Arenula, 70 - 00186 Roma (RM)", "Numero Telefonico"=>"06 68851"}
{"Tipo"=>"AOO", "Nome"=>"Archivio Notarile Distrettuale di Agrigento", "Indirizzo e-mail"=>"[email protected]", "Tipo email"=>"PEC", "Responsabile"=>"Daniela Portera", "Indirizzo"=>"Via S. Vito, 97/103 - 92100 Agrigento (AG)", "Numero Telefonico"=>"09 2220290"}
{"Tipo"=>"AOO", "Nome"=>"Archivio Notarile Distrettuale di Alessandria", "Indirizzo e-mail"=>"[email protected]", "Tipo email"=>"PEC", "Responsabile"=>"Susanna Cesarone Bongiorno", "Indirizzo"=>"Via Ghilini, 42 - 15121 Alessandria (AL)", "Numero Telefonico"=>"01 31254163"}
{"Tipo"=>"AOO", "Nome"=>"Archivio Notarile Distrettuale di Ancona", "Indirizzo e-mail"=>"[email protected]", "Tipo email"=>"PEC", "Responsabile"=>"Margherita Regini Santojanni", "Indirizzo"=>"Piazzale Europa, 7 - 60125 Ancona (AN)", "Numero Telefonico"=>"07 12804055"}
{"Tipo"=>"AOO", "Nome"=>"Archivio Notarile Distrettuale di Aosta", "Indirizzo e-mail"=>"[email protected]", "Tipo email"=>"PEC", "Responsabile"=>"Antonio Santoro", "Indirizzo"=>"Via Monsignor De Sales, 3 - 11100 Aosta (AO)", "Numero Telefonico"=>"01 65361395"}
{"Tipo"=>"AOO", "Nome"=>"Archivio Notarile Distrettuale di Arezzo", "Indirizzo e-mail"=>"[email protected]", "Tipo email"=>"PEC", "Responsabile"=>"Gianna Baroni Pedone", "Indirizzo"=>"Via Francesco Crispi, 58/4 - 52100 Arezzo (AR)", "Numero Telefonico"=>"05 7523243"}
But in the database I'm not able to store these data. Someone can help me please? Sorry in advance if I have forgotten something to tell you.
I've never worked with the "roo" gem, but looking a bit at their documentation and code. Something like this should do the job:
Since the header names in the sheet and attribute names of the models are different you need to convert the row returned, which should be a core Hash instance.
You can retrieve the values of the fields using
fetch_values(raises an exception when a key is missing) orvalues_at(returns the default value when a key is missing, which when not set isnil). Thenzipthe headers of the model with the values and convert the whole thing back into a hash.Then use
create!to create anCourtinstance and save it to the database. This raises an exception when something goes wrong rolling back thetransaction. You could also usecreate, but this doesn't raise an exception. Meaning that invalid records are silently swallowed and simply not saved.One thing to point out is that your current output shows
"Tipo"=>"AMM", where"AMM"is the type I'm guessing. However this is not an id, so you might need to fetch the type ids and maybe other ids first before attempting to save.Something like this: