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
|
# File 'lib/uploadbox/image_uploader.rb', line 3
def uploads_one(upload_name, options={})
default_options = {
default: false,
placeholder: false,
removable: true,
retina: Uploadbox.retina,
quality: Uploadbox.retina ? (Uploadbox.retina_quality || 40) : (Uploadbox.image_quality || 80)
}
options = options.reverse_merge(default_options)
upload_versions = options.select{ |key| default_options.keys.exclude? key }
options = options.select{ |key| default_options.keys.include? key }
imageable_type = self.to_s
upload_class_name = imageable_type + upload_name.to_s.camelize
upload_class = Class.new(Image)
Uploadbox.instance_eval {remove_const upload_class_name} if Uploadbox.const_defined?(upload_class_name)
Uploadbox.const_set(upload_class_name, upload_class)
define_method("#{upload_name}?") do
upload = send("#{upload_name}_upload")
!!(upload and (upload.processing? or upload.file?))
end
define_method(upload_name) do
upload = send("#{upload_name}_upload")
if upload
upload
else
image = Struct.new(:url, :width, :height) do
def to_s
url
end
def processing?
false
end
end
placeholder = Class.new do
upload_versions.keys.each do |version|
define_method(version) do
width = upload_versions[version][0]
height = upload_versions[version][1]
image.new("#{version}_#{options[:placeholder]}", width, height)
end
end
end
placeholder.new
end
end
define_method("#{upload_name}=") do |upload_or_id|
if upload_or_id.is_a? ActionDispatch::Http::UploadedFile
upload = upload_class.create(file: upload_or_id)
self.send("#{upload_name}_upload=", upload)
elsif upload_or_id.present?
self.send("#{upload_name}_upload=", upload_class.find(upload_or_id))
end
end
define_method("remote_#{upload_name}_url=") do |url|
upload = Uploadbox.const_get(upload_class_name).create!(remote_file_url: url)
self.send("#{upload_name}_upload=", upload)
end
self.define_singleton_method "update_#{upload_name}_versions!" do
Uploadbox.const_get(upload_class_name).find_each{ |upload| upload.file.recreate_versions! if upload.file? }
end
upload_class.define_singleton_method :versions do
upload_versions
end
upload_class.define_singleton_method :removable? do
options[:removable]
end
upload_class.instance_eval do
delegate *upload_versions.keys, to: :file
default_scope -> { where(imageable_type: imageable_type).where(upload_name: upload_name.to_s) }
dynamic_uploader = Class.new(Uploadbox::ImageProcessingUploader)
unless Uploadbox.const_defined?(self.name.demodulize + 'Uploader')
Uploadbox.const_set(self.name.demodulize + 'Uploader', dynamic_uploader)
end
dynamic_uploader.class_eval do
upload_versions.each do |version_name, dimensions|
if options[:retina]
dimensions = dimensions.map{ |d| d * 2 }
end
version version_name do
process resize_to_fill: dimensions
process quality: quality = options[:quality]
end
def dimensions
model.class.versions[version_name]
end
def width
dimensions[0]
end
def height
dimensions[1]
end
def processing?
model.processing?
end
def original_file
model.original_file
end
end
end
mount_uploader :file, dynamic_uploader
end
has_one "#{upload_name}_upload".to_sym, as: :imageable,
class_name: "Uploadbox::#{self.to_s + upload_name.to_s.camelize}",
autosave: true
accepts_nested_attributes_for "#{upload_name}_upload".to_sym
end
|