mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-11-14 21:24:54 +08:00
186 lines
5.2 KiB
Ruby
186 lines
5.2 KiB
Ruby
class Repository < ApplicationRecord
|
|
include SearchableModel
|
|
|
|
belongs_to :team, optional: true
|
|
belongs_to :created_by,
|
|
foreign_key: :created_by_id,
|
|
class_name: 'User',
|
|
optional: true
|
|
has_many :repository_columns
|
|
has_many :repository_rows
|
|
has_many :repository_table_states,
|
|
inverse_of: :repository, dependent: :destroy
|
|
has_many :report_elements, inverse_of: :repository, dependent: :destroy
|
|
|
|
auto_strip_attributes :name, nullify: false
|
|
validates :name,
|
|
presence: true,
|
|
uniqueness: { scope: :team, case_sensitive: false },
|
|
length: { maximum: Constants::NAME_MAX_LENGTH }
|
|
validates :team, presence: true
|
|
validates :created_by, presence: true
|
|
|
|
def self.search(
|
|
user,
|
|
_include_archived,
|
|
query = nil,
|
|
page = 1,
|
|
current_team = nil,
|
|
options = {}
|
|
)
|
|
team_ids =
|
|
if current_team
|
|
current_team.id
|
|
else
|
|
Team.joins(:user_teams)
|
|
.where('user_teams.user_id = ?', user.id)
|
|
.distinct
|
|
.pluck(:id)
|
|
end
|
|
|
|
row_ids = RepositoryRow
|
|
.search(nil, query, Constants::SEARCH_NO_LIMIT, options)
|
|
.select(:id)
|
|
|
|
new_query = Repository
|
|
.select('repositories.*, COUNT(repository_rows.id) AS counter')
|
|
.joins(:team)
|
|
.joins('LEFT OUTER JOIN repository_rows ON ' \
|
|
'repositories.id = repository_rows.repository_id')
|
|
.where(team: team_ids)
|
|
.where('repository_rows.id IN (?)', row_ids)
|
|
.group('repositories.id')
|
|
|
|
# Show all results if needed
|
|
if page == Constants::SEARCH_NO_LIMIT
|
|
new_query
|
|
else
|
|
new_query
|
|
.limit(Constants::SEARCH_LIMIT)
|
|
.offset((page - 1) * Constants::SEARCH_LIMIT)
|
|
end
|
|
end
|
|
|
|
def available_repository_fields
|
|
fields = {}
|
|
# First and foremost add record name
|
|
fields['-1'] = I18n.t('repositories.default_column')
|
|
# Add all other custom columns
|
|
repository_columns.order(:created_at).each do |rc|
|
|
fields[rc.id] = rc.name
|
|
end
|
|
fields
|
|
end
|
|
|
|
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
|
|
|
|
# Imports records
|
|
def import_records(sheet, mappings, user)
|
|
errors = false
|
|
columns = []
|
|
name_index = -1
|
|
total_nr = 0
|
|
nr_of_added = 0
|
|
header_skipped = false
|
|
|
|
mappings.each.with_index do |(_k, value), index|
|
|
if value == '-1'
|
|
# Fill blank space, so our indices stay the same
|
|
columns << nil
|
|
name_index = index
|
|
else
|
|
columns << repository_columns.find_by_id(value)
|
|
end
|
|
end
|
|
|
|
# Check for duplicate columns
|
|
col_compact = columns.compact
|
|
unless col_compact.map(&:id).uniq.length == col_compact.length
|
|
return { status: :error, nr_of_added: nr_of_added, total_nr: total_nr }
|
|
end
|
|
rows = SpreadsheetParser.spreadsheet_enumerator(sheet)
|
|
|
|
# Now we can iterate through record data and save stuff into db
|
|
rows.each do |row|
|
|
# Skip empty rows
|
|
next if row.empty?
|
|
unless header_skipped
|
|
header_skipped = true
|
|
next
|
|
end
|
|
total_nr += 1
|
|
|
|
# Creek XLSX parser returns Hash of the row, Roo - Array
|
|
row = row.is_a?(Hash) ? row.values.map(&:to_s) : row.map(&:to_s)
|
|
|
|
record_row = RepositoryRow.new(name: row[name_index],
|
|
repository: self,
|
|
created_by: user,
|
|
last_modified_by: user)
|
|
record_row.transaction do
|
|
unless record_row.save
|
|
errors = true
|
|
raise ActiveRecord::Rollback
|
|
end
|
|
|
|
row_cell_values = []
|
|
|
|
row.each.with_index do |value, index|
|
|
if columns[index] && value
|
|
cell_value = RepositoryTextValue.new(
|
|
data: value,
|
|
created_by: user,
|
|
last_modified_by: user,
|
|
repository_cell_attributes: {
|
|
repository_row: record_row,
|
|
repository_column: columns[index]
|
|
}
|
|
)
|
|
unless cell_value.valid?
|
|
errors = true
|
|
raise ActiveRecord::Rollback
|
|
end
|
|
row_cell_values << cell_value
|
|
end
|
|
end
|
|
if RepositoryTextValue.import(row_cell_values,
|
|
recursive: true,
|
|
validate: false).failed_instances.any?
|
|
errors = true
|
|
raise ActiveRecord::Rollback
|
|
end
|
|
nr_of_added += 1
|
|
end
|
|
end
|
|
|
|
if errors
|
|
return { status: :error, nr_of_added: nr_of_added, total_nr: total_nr }
|
|
end
|
|
{ status: :ok, nr_of_added: nr_of_added, total_nr: total_nr }
|
|
end
|
|
end
|