-
Notifications
You must be signed in to change notification settings - Fork 194
/
attachable.rb
148 lines (121 loc) · 3.5 KB
/
attachable.rb
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
module Attachable
extend ActiveSupport::Concern
included do
has_many :attachments,
-> { not_deleted.order('attachments.ordering, attachments.id') },
as: :attachable,
inverse_of: :attachable
has_many :html_attachments,
-> { not_deleted.order('attachments.ordering, attachments.id') },
as: :attachable
has_many :deleted_html_attachments,
-> { deleted },
class_name: "HtmlAttachment",
as: :attachable
if respond_to?(:add_trait)
add_trait do
def process_associations_after_save(edition)
@edition.attachments.each do |attachment|
edition.attachments << attachment.deep_clone
end
end
end
end
end
def build_empty_file_attachment
attachment = FileAttachment.new
attachment.build_attachment_data
attachments << attachment
end
def valid_virus_state?
attachments.each do |attachment|
if attachment.could_contain_viruses? && (attachment.virus_status != :clean)
return false
end
end
true
end
def allows_attachments?
true
end
def allows_file_attachments?
true
end
def allows_attachment_references?
false
end
def allows_inline_attachments?
true
end
def can_order_attachments?
!allows_inline_attachments?
end
def can_have_attached_house_of_commons_papers?
false
end
def allows_html_attachments?
false
end
def allows_external_attachments?
false
end
def allows_attachment_type?(type)
case type
when "html"
allows_html_attachments?
when "external"
allows_external_attachments?
when "file"
allows_file_attachments?
else
false
end
end
def has_thumbnail?
thumbnailable_attachments.any?
end
def thumbnail_url
thumbnailable_attachments.first.url(:thumbnail)
end
def thumbnailable_attachments
attachments.select { |a| a.content_type == AttachmentUploader::PDF_CONTENT_TYPE }
end
def has_official_document?
has_command_paper? || has_act_paper?
end
def has_command_paper?
attachments.any?(&:is_command_paper?)
end
def has_act_paper?
attachments.any?(&:is_act_paper?)
end
def search_index
super.merge("attachments" => attachments.map(&:search_index))
end
def next_ordering
max = Attachment.where(attachable_id: id, attachable_type: self.class.base_class.to_s).maximum(:ordering)
max ? max + 1 : 0
end
def delete_all_attachments
attachments.each { |attachment| attachment.update(deleted: true) }
end
def reorder_attachments(ordered_attachment_ids)
return if ordered_attachment_ids.empty?
transaction do
# Attachment has a unique constraint on attachable type/id and ordering.
# This stops us simply changing the ordering values of existing
# attachments, as two rows end up with the same ordering value during
# the update, violating the constraint.
# To get around it, we check that we can start at 0 and fit all the
# ordering values below the current lowest ordering.
start_at = if ordered_attachment_ids.count < attachments.unscoped.minimum(:ordering)
0
else # Otherwise, we start reordering at the next available number
next_ordering
end
ordered_attachment_ids.each.with_index(start_at) do |attachment_id, ordering|
attachments.find(attachment_id).update_column(:ordering, ordering)
end
end
end
end