-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathtask_file.rb
More file actions
89 lines (72 loc) · 2.55 KB
/
Copy pathtask_file.rb
File metadata and controls
89 lines (72 loc) · 2.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# frozen_string_literal: true
class TaskFile < ApplicationRecord
include ParentValidation
include TransferValues
belongs_to :fileable, polymorphic: true
belongs_to :parent, class_name: 'TaskFile', optional: true
has_one_attached :attachment
validates :name, presence: true
validates :attachment, presence: true, if: -> { use_attached_file == 'true' }, on: :force_validations
validates :xml_id, presence: true
validates :visible, inclusion: {in: %w[yes no delayed]}
validates :used_by_grader, inclusion: {in: [true, false]}
validates :parent_id, uniqueness: {scope: %i[fileable_id fileable_type]}, if: -> { parent_id.present? }
validate :unique_xml_id, if: -> { !fileable.nil? }
validate :parent_validation_check
attr_accessor :use_attached_file, :file_marked_for_deletion, :parent_blob_id
before_validation :attach_parent_blob, if: -> { attachment.blank? && task&.contribution? && parent.present? && parent_blob_id.present? }
before_save :remove_attachment
def task
return nil unless fileable
if fileable.is_a?(Task)
# This file is directly attached to a task
fileable
else
# This file is part of a model solution, or test
fileable.task
end
end
def full_file_name
path.present? ? File.join(path.to_s, name) : name
end
def full_file_name=(full_file_name)
path = File.dirname(full_file_name)
self.path = path == '.' ? '' : path
self.name = File.basename(full_file_name)
end
def duplicate(set_parent_id: true)
dup.tap do |file|
if attachment.attached?
file.attachment.attach(attachment.blob)
file.use_attached_file = 'true'
end
if set_parent_id
file.parent_id = id
end
end
end
def text_data?
return false unless (content = attachment&.blob&.download)
content.encode('UTF-8', 'binary')
true
rescue Encoding::UndefinedConversionError => _e
false
end
def extract_text_data
attachment.blob.download
end
private
def attach_parent_blob
# The comparison of the blob ID is used as a safeguard to ensure updated files in a task contribution are not overwritten unintended.
return unless parent_blob_id.to_i == parent.attachment.blob.id
attachment.attach(parent.attachment.blob)
end
def remove_attachment
attachment.purge if use_attached_file != 'true' && attachment.present?
end
def unique_xml_id
task = fileable.is_a?(Task) ? fileable : fileable.task
xml_ids = (task.all_files - [self]).map(&:xml_id)
errors.add(:xml_id, :not_unique) if xml_ids.include? xml_id
end
end