1
1
module Api ::V1
2
2
class ExercisesController < OpenStax ::Api ::V1 ::ApiController
3
3
4
- before_filter :get_exercise , only : [ :show , :update , :destroy ]
4
+ before_filter :get_exercise_or_create_draft , only : [ :show , :update ]
5
+ before_filter :get_exercise , only : [ :destroy ]
5
6
6
7
resource_description do
7
8
api_versions "v1"
@@ -21,7 +22,7 @@ class ExercisesController < OpenStax::Api::V1::ApiController
21
22
of the matching Exercises. Only Exercises visible to the caller will be
22
23
returned. The schema for the returned JSON result is shown below.
23
24
24
- #{ json_schema ( Api ::V1 ::ExerciseSearchRepresenter , include : :readable ) }
25
+ #{ json_schema ( Api ::V1 ::ExerciseSearchRepresenter , include : :readable ) }
25
26
EOS
26
27
# Using route helpers doesn't work in test or production, probably has to do with initialization order
27
28
example "#{ api_example ( url_base : 'https://exercises.openstax.org/api/exercises' ,
@@ -44,7 +45,7 @@ class ExercisesController < OpenStax::Api::V1::ApiController
44
45
(uses wildcard matching)
45
46
* `number` – Matches the exercise number exactly.
46
47
* `version` – Matches the exercise version exactly.
47
- * `id` – Matches the exercise ID exactly.
48
+ * `id` – Matches the exercise ID or UID exactly.
48
49
* `published_before` – Matches exercises published before the given date.
49
50
Enclose date in quotes to avoid parsing errors.
50
51
@@ -67,7 +68,7 @@ class ExercisesController < OpenStax::Api::V1::ApiController
67
68
The fields can be one of #{
68
69
SearchExercises ::SORTABLE_FIELDS . keys . collect { |sf | "`" +sf +"`" } . join ( ', ' )
69
70
} .
70
- Sort directions can either be `ASC` for
71
+ Sort directions can either be `ASC` for
71
72
an ascending sort, or `DESC` for a
72
73
descending sort. If not provided, an ascending sort is assumed. Sort
73
74
directions should be separated from the fields by a space.
@@ -78,7 +79,8 @@ class ExercisesController < OpenStax::Api::V1::ApiController
78
79
`number, version DESC` – sorts by number ascending, then by version descending
79
80
EOS
80
81
def index
81
- standard_search ( Exercise , SearchExercises , ExerciseSearchRepresenter , user : current_api_user )
82
+ standard_search ( Exercise , SearchExercises , ExerciseSearchRepresenter ,
83
+ user : current_api_user )
82
84
end
83
85
84
86
##########
@@ -89,7 +91,7 @@ def index
89
91
description <<-EOS
90
92
Creates an Exercise with the given attributes.
91
93
92
- #{ json_schema ( Api ::V1 ::ExerciseRepresenter , include : :writeable ) }
94
+ #{ json_schema ( Api ::V1 ::ExerciseRepresenter , include : :writeable ) }
93
95
EOS
94
96
def create
95
97
user = current_human_user
@@ -108,11 +110,11 @@ def create
108
110
# show #
109
111
########
110
112
111
- api :GET , '/exercises/:id ' , 'Gets the specified Exercise'
113
+ api :GET , '/exercises/:uid ' , 'Gets the specified Exercise'
112
114
description <<-EOS
113
- Gets the Exercise that matches the provided ID .
115
+ Gets the Exercise that matches the provided UID .
114
116
115
- #{ json_schema ( Api ::V1 ::ExerciseRepresenter , include : :readable ) }
117
+ #{ json_schema ( Api ::V1 ::ExerciseRepresenter , include : :readable ) }
116
118
EOS
117
119
def show
118
120
standard_read ( @exercise )
@@ -122,11 +124,11 @@ def show
122
124
# update #
123
125
##########
124
126
125
- api :PUT , '/exercises/:id ' , 'Updates the specified Exercise'
127
+ api :PUT , '/exercises/:uid ' , 'Updates the specified Exercise'
126
128
description <<-EOS
127
- Updates the Exercise that matches the provided ID with the given attributes.
129
+ Updates the Exercise that matches the provided UID with the given attributes.
128
130
129
- #{ json_schema ( Api ::V1 ::ExerciseRepresenter , include : :writeable ) }
131
+ #{ json_schema ( Api ::V1 ::ExerciseRepresenter , include : :writeable ) }
130
132
EOS
131
133
def update
132
134
standard_update ( @exercise )
@@ -136,9 +138,9 @@ def update
136
138
# destroy #
137
139
###########
138
140
139
- api :DELETE , '/exercises/:id ' , 'Deletes the specified Exercise'
141
+ api :DELETE , '/exercises/:uid ' , 'Deletes the specified Exercise'
140
142
description <<-EOS
141
- Deletes the Exercise that matches the provided ID .
143
+ Deletes the Exercise that matches the provided UID .
142
144
EOS
143
145
def destroy
144
146
standard_destroy ( @exercise )
@@ -150,6 +152,21 @@ def get_exercise
150
152
@exercise = Exercise . visible_for ( current_api_user ) . with_uid ( params [ :id ] ) . first || \
151
153
raise ( ActiveRecord ::RecordNotFound , "Couldn't find Exercise with 'uid'=#{ params [ :id ] } " )
152
154
end
153
-
155
+
156
+ def get_exercise_or_create_draft
157
+ @exercise = Exercise . visible_for ( current_api_user ) . with_uid ( params [ :id ] ) . first
158
+ return unless @exercise . nil?
159
+
160
+ @number , @version = params [ :id ] . split ( '@' )
161
+ draft_requested = @version == 'draft' || @version == 'd'
162
+ raise ( ActiveRecord ::RecordNotFound , "Couldn't find Exercise with 'uid'=#{ params [ :id ] } " ) \
163
+ unless draft_requested
164
+
165
+ published_exercise = Exercise . visible_for ( current_api_user ) . with_uid ( @number ) . first || \
166
+ raise ( ActiveRecord ::RecordNotFound , "Couldn't find Exercise with 'uid'=#{ params [ :id ] } " )
167
+ @exercise = published_exercise . new_version
168
+ @exercise . save!
169
+ end
170
+
154
171
end
155
172
end
0 commit comments