2017-06-23 21:19:08 +08:00
|
|
|
class Repository < ApplicationRecord
|
2017-06-28 21:21:32 +08:00
|
|
|
belongs_to :team, optional: true
|
|
|
|
belongs_to :created_by,
|
|
|
|
foreign_key: :created_by_id,
|
|
|
|
class_name: 'User',
|
|
|
|
optional: true
|
2017-05-16 21:27:36 +08:00
|
|
|
has_many :repository_columns
|
|
|
|
has_many :repository_rows
|
2017-06-07 19:36:39 +08:00
|
|
|
has_many :repository_table_states,
|
|
|
|
inverse_of: :repository, dependent: :destroy
|
2017-06-05 18:24:06 +08:00
|
|
|
has_many :report_elements, inverse_of: :repository, dependent: :destroy
|
2017-05-16 21:27:36 +08:00
|
|
|
|
|
|
|
auto_strip_attributes :name, nullify: false
|
|
|
|
validates :name,
|
|
|
|
presence: true,
|
2017-06-05 16:38:04 +08:00
|
|
|
uniqueness: { scope: :team, case_sensitive: false },
|
2017-05-16 21:27:36 +08:00
|
|
|
length: { maximum: Constants::NAME_MAX_LENGTH }
|
|
|
|
validates :team, presence: true
|
|
|
|
validates :created_by, presence: true
|
2017-05-30 14:57:00 +08:00
|
|
|
|
2017-06-13 14:10:10 +08:00
|
|
|
def open_spreadsheet(file)
|
|
|
|
filename = file.original_filename
|
|
|
|
file_path = file.path
|
|
|
|
|
|
|
|
if file.class == Paperclip::Attachment && file.is_stored_on_s3?
|
|
|
|
fa = file.fetch
|
|
|
|
file_path = fa.path
|
|
|
|
end
|
|
|
|
generate_file(filename, file_path)
|
|
|
|
end
|
|
|
|
|
|
|
|
def available_repository_fields
|
|
|
|
fields = {}
|
2017-06-21 23:39:20 +08:00
|
|
|
# First and foremost add record name
|
2017-06-21 20:45:50 +08:00
|
|
|
fields['-1'] = I18n.t('repositories.default_column')
|
2017-06-13 14:10:10 +08:00
|
|
|
# Add all other custom columns
|
|
|
|
repository_columns.order(:created_at).each do |rc|
|
|
|
|
fields[rc.id] = rc.name
|
|
|
|
end
|
|
|
|
fields
|
|
|
|
end
|
|
|
|
|
2017-05-30 14:57:00 +08:00
|
|
|
def copy(created_by, name)
|
|
|
|
new_repo = nil
|
|
|
|
|
|
|
|
begin
|
|
|
|
Repository.transaction do
|
|
|
|
# Clone the repository object
|
|
|
|
new_repo = dup
|
|
|
|
new_repo.created_by = created_by
|
|
|
|
new_repo.name = name
|
|
|
|
new_repo.save!
|
|
|
|
|
|
|
|
# Clone columns (only if new_repo was saved)
|
|
|
|
repository_columns.find_each do |col|
|
|
|
|
new_col = col.dup
|
|
|
|
new_col.repository = new_repo
|
|
|
|
new_col.created_by = created_by
|
|
|
|
new_col.save!
|
|
|
|
end
|
|
|
|
end
|
|
|
|
rescue ActiveRecord::RecordInvalid
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
# If everything is okay, return new_repo
|
|
|
|
new_repo
|
|
|
|
end
|
2017-06-13 14:10:10 +08:00
|
|
|
|
2017-06-19 20:05:37 +08:00
|
|
|
# Imports records
|
|
|
|
def import_records(sheet, mappings, user)
|
|
|
|
errors = []
|
|
|
|
custom_fields = []
|
|
|
|
name_index = -1
|
2017-06-21 15:31:39 +08:00
|
|
|
nr_of_added = 0
|
2017-06-19 20:05:37 +08:00
|
|
|
|
2017-06-21 21:01:55 +08:00
|
|
|
mappings.each.with_index do |(_k, value), index|
|
|
|
|
if value == '-1'
|
2017-06-19 20:05:37 +08:00
|
|
|
# Fill blank space, so our indices stay the same
|
|
|
|
custom_fields << nil
|
2017-06-21 21:01:55 +08:00
|
|
|
name_index = index
|
2017-06-19 20:05:37 +08:00
|
|
|
else
|
2017-06-21 21:01:55 +08:00
|
|
|
cf = repository_columns.find_by_id(value)
|
2017-06-19 20:05:37 +08:00
|
|
|
custom_fields << cf
|
|
|
|
end
|
|
|
|
end
|
2017-06-21 15:31:39 +08:00
|
|
|
|
2017-06-21 23:39:20 +08:00
|
|
|
# Now we can iterate through record data and save stuff into db
|
2017-06-19 20:05:37 +08:00
|
|
|
(2..sheet.last_row).each do |i|
|
|
|
|
error = []
|
|
|
|
record_row = RepositoryRow.new(name: sheet.row(i)[name_index],
|
|
|
|
repository: self,
|
|
|
|
created_by: user,
|
|
|
|
last_modified_by: user)
|
|
|
|
|
2017-06-22 21:21:36 +08:00
|
|
|
next unless record_row.valid?
|
2017-06-21 21:01:55 +08:00
|
|
|
sheet.row(i).each.with_index do |value, index|
|
2017-06-22 21:21:36 +08:00
|
|
|
if custom_fields[index] && value
|
2017-06-21 21:01:55 +08:00
|
|
|
rep_column = RepositoryTextValue.new(
|
|
|
|
data: value,
|
|
|
|
created_by: user,
|
|
|
|
last_modified_by: user,
|
|
|
|
repository_cell_attributes: {
|
|
|
|
repository_row: record_row,
|
|
|
|
repository_column: custom_fields[index]
|
|
|
|
}
|
|
|
|
)
|
|
|
|
error << rep_column.errors.messages unless rep_column.save
|
2017-06-19 20:05:37 +08:00
|
|
|
end
|
|
|
|
end
|
2017-06-22 21:21:36 +08:00
|
|
|
if error.any?
|
|
|
|
record_row.destroy
|
|
|
|
else
|
|
|
|
nr_of_added += 1
|
|
|
|
record_row.save
|
|
|
|
end
|
2017-06-19 20:05:37 +08:00
|
|
|
end
|
2017-06-21 15:31:39 +08:00
|
|
|
|
2017-06-19 20:05:37 +08:00
|
|
|
if errors.count > 0
|
2017-06-21 20:45:50 +08:00
|
|
|
return { status: :error, errors: errors, nr_of_added: nr_of_added }
|
2017-06-19 20:05:37 +08:00
|
|
|
end
|
2017-06-21 20:45:50 +08:00
|
|
|
{ status: :ok, nr_of_added: nr_of_added }
|
2017-06-19 20:05:37 +08:00
|
|
|
end
|
|
|
|
|
2017-06-13 14:10:10 +08:00
|
|
|
private
|
|
|
|
|
|
|
|
def generate_file(filename, file_path)
|
|
|
|
case File.extname(filename)
|
|
|
|
when '.csv'
|
|
|
|
Roo::CSV.new(file_path, extension: :csv)
|
|
|
|
when '.tdv'
|
|
|
|
Roo::CSV.new(file_path, nil, :ignore, csv_options: { col_sep: '\t' })
|
|
|
|
when '.txt'
|
|
|
|
# This assumption is based purely on biologist's habits
|
|
|
|
Roo::CSV.new(file_path, csv_options: { col_sep: '\t' })
|
|
|
|
when '.xls'
|
|
|
|
Roo::Excel.new(file_path)
|
|
|
|
when '.xlsx'
|
|
|
|
Roo::Excelx.new(file_path)
|
|
|
|
else
|
|
|
|
raise TypeError
|
|
|
|
end
|
|
|
|
end
|
2017-05-16 21:27:36 +08:00
|
|
|
end
|