-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.rb
129 lines (102 loc) · 3.03 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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# frozen_string_literal: true
require 'sinatra'
require 'rack/contrib'
require 'sinatra/activerecord'
require 'json'
use Rack::PostBodyContentTypeParser
configure do
set :allow_origin, :any
set :allow_methods, %i[get post options delete put patch]
enable :cross_origin
# Load model
require './models/todo'
end
options '*' do
response.headers['Allow'] = 'HEAD,GET,PUT,POST,OPTIONS,DELETE,PATCH'
response.headers['Access-Control-Allow-Headers'] = 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Cache-Control, Accept'
end
before { content_type :json }
get '/' do
err 404, 'Route does not exist'
end
# Collection Actions
get '/todos/?' do
if Todo.count > 0
Todo.select(:id, :title).to_json
else
err 400, 'There are no todos yet'
end
end
# Accepts title, due and notes as querystring, form-data or JSON body
post '/todos/?' do
title = params['title']
due = params['due']
notes = params['notes'] || ''
if title && due
todo = Todo.new title: title, due: parse_date(due), notes: notes
if todo.save!
status 201
todo.to_json
else
err 500, 'Todo could not be saved in the database'
end
else
err 422, 'You must provide `title` and `due` as a) QueryString parameters, b) form-data or c) JSON in the request body. The choice is yours.'
end
end
put('/todos/?') { err 405, 'You cannot modify the collection directly' }
patch('/todos/?') { err 405, 'You cannot modify the collection directly' }
delete('/todos/?') { err 405, 'You cannot delete the collection' }
# Object Actions
get '/todos/:id/?' do |id|
get_todo(id).to_json
end
put '/todos/:id/?' do |id|
todo = get_todo(id)
# Throw error if not all fields are present
unless params['title'] && parse_date(params['due']) && params['notes']
err 422, 'You must include all fields for a PUT: `title`, `due` and `notes` must be present'
end
todo.title = params['title'] if params.key?('title')
todo.due = parse_date(params['due']) if params.key?('due')
todo.notes = params['notes'] if params.key?('notes')
if todo.save!
todo.to_json
else
err 500, 'Todo could not be updated in the database'
end
end
patch '/todos/:id/?' do |id|
todo = get_todo(id)
todo.title = params['title'] if params.key?('title')
todo.due = parse_date(params['due']) if params.key?('due')
todo.notes = params['notes'] if params.key?('notes')
if todo.save!
todo.to_json
else
err 500, 'Todo could not be updated in the database'
end
end
delete '/todos/:id/?' do |id|
if get_todo(id).destroy
halt 204
else
err 500, 'Todo could not be deleted'
end
end
post('/todos/:id/?') { err 405, 'You cannot POST to this object' }
private
def err(code, message)
body({ error_message: message.to_s }.to_json)
halt code.to_i
end
def parse_date(date)
Date.parse date
rescue ArgumentError => e
err 422, 'Due Date must be and ISO 8601 String: YYYY-MM-DD'
end
def get_todo(id)
Todo.find(id)
rescue ActiveRecord::RecordNotFound => e
err 404, 'Todo item not found'
end