This repository has been archived by the owner on Nov 22, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.rb
115 lines (94 loc) · 3.93 KB
/
app.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
require "./config/rom"
require "./config/shrine"
require "./config/objects"
require "roda"
class App < Roda
plugin :all_verbs
plugin :json, serializer: ->(object) { JSON.pretty_generate(object) }
route do |r|
r.on "articles" do
r.is do
r.post do
attacher = ImageUploader::Attacher.new(Article.new, :image)
# If params["image"] is a new raw file, upload it to cache. If the
# file is already uploaded (e.g. retained on valiation errors or
# directly uploaded), it proceeeds only if it's uploaded to cache,
# for security reasons.
#
# In both cases this runs validations, and records that attachment
# has changed so that it promotes the cached file to permanent
# storage and deletes the previous attachment in Attacher#finalize.
if r.params["image"]
attacher.assign(r.params["image"])
r.params["image"] = attacher.read
end
validation = ArticleSchema.call(r.params)
# Adds Shrine's file validation errors that were performed on
# Attacher#assign.
validation.messages[:image] = attacher.errors
if validation.success?
attributes = validation.output
# Even though the attachment parameter is named "image", the column
# has to be named "image_data", because that's how it works best
# with ORMs which implement the Active Record pattern.
attributes[:image_data] = attributes.delete(:image)
article = articles_repo.create(attributes)
# Attacher#finalize will kick off a background job, and the
# backgrounding plugin needs the created/updated record in order to
# know whether it needs to kick off a background job, and to be
# able to send the record class & ID, cached file, and other
# information to background job's arguments.
attacher.context[:record] = Article.new(article.to_h)
# Promotes the cached file to permanent storage (either
# synchronously or by spawning a background job), if the attachment
# is assigned. It also deletes any previous attached files (again,
# either synchronously or by spawning a background job).
attacher.finalize if attacher.attached?
Presenters::Article.new(article).to_h
else
response.status = 400
validation.messages
end
end
end
r.is ":id" do |id|
r.get do
article = articles_repo.by_id(id)
Presenters::Article.new(article).to_h
end
r.put do
article = articles_repo.by_id(id)
attacher = ImageUploader::Attacher.new(article, :image)
if r.params["image"]
attacher.assign(r.params["image"])
r.params["image"] = attacher.read
end
validation = ArticleSchema.call(article.to_h.merge(r.params))
validation.messages[:image] = attacher.errors
if validation.success?
attributes = validation.output
attributes[:image_data] = attributes.delete(:image)
article = articles_repo.update(article.id, attributes)
attacher.context[:record] = Article.new(article.to_h)
attacher.finalize if attacher.attached?
Presenters::Article.new(article).to_h
else
response.status = 400
validation.messages
end
end
r.delete do
article = articles_repo.by_id(id)
articles_repo.delete(article.id)
attacher = ImageUploader::Attacher.new(article, :image)
# Deletes the attached files if the record had them (either
# synchronously or by spawning a background job).
attacher.destroy
end
end
end
end
def articles_repo
Repositories::Articles.new($rom)
end
end