Skip to content

Commit cc7e92d

Browse files
committed
Add a page listing all valid category slugs
To direct people to when they have specified an invalid slug. JSON containing all the slugs is available at /api/v1/category_slugs, but visiting that in a browser doesn't work.
1 parent 8db77c4 commit cc7e92d

File tree

7 files changed

+64
-0
lines changed

7 files changed

+64
-0
lines changed

app/adapters/category-slug.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import ApplicationAdapter from './application';
2+
import Ember from 'ember';
3+
4+
export default ApplicationAdapter.extend({
5+
pathForType(modelName) {
6+
var decamelized = Ember.String.underscore(
7+
Ember.String.decamelize(modelName)
8+
);
9+
return Ember.String.pluralize(decamelized);
10+
}
11+
});

app/models/category-slug.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import DS from 'ember-data';
2+
3+
export default DS.Model.extend({
4+
slug: DS.attr('string'),
5+
});

app/router.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Router.map(function() {
3939
this.route('category', { path: '/categories/:category_id' }, function() {
4040
this.route('index', { path: '/' });
4141
});
42+
this.route('category_slugs');
4243
this.route('catchAll', { path: '*path' });
4344
});
4445

app/routes/category-slugs.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import Ember from 'ember';
2+
3+
export default Ember.Route.extend({
4+
queryParams: {
5+
page: { refreshModel: true },
6+
sort: { refreshModel: true },
7+
},
8+
9+
model(params) {
10+
return this.store.query('category-slug', params);
11+
},
12+
});

app/templates/category_slugs.hbs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{{ title 'Category Slugs' }}
2+
3+
<div id='crates-heading'>
4+
<img class='logo crate' src="/assets/crate.png"/>
5+
<h1>All Valid Category Slugs</h1>
6+
</div>
7+
8+
<div class='white-rows'>
9+
<ul>
10+
{{#each model as |slug|}}
11+
<li>{{slug.slug}}</li>
12+
{{/each}}
13+
</ul>
14+
</div>

src/category.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,3 +233,23 @@ pub fn show(req: &mut Request) -> CargoResult<Response> {
233233
struct R { category: EncodableCategoryWithSubcategories}
234234
Ok(req.json(&R { category: cat_with_subcats }))
235235
}
236+
237+
/// Handles the `GET /category_slugs` route.
238+
pub fn slugs(req: &mut Request) -> CargoResult<Response> {
239+
let conn = try!(req.tx());
240+
let stmt = try!(conn.prepare("SELECT slug FROM categories \
241+
ORDER BY slug"));
242+
let rows = try!(stmt.query(&[]));
243+
244+
#[derive(RustcEncodable)]
245+
struct Slug { id: String, slug: String }
246+
247+
let slugs: Vec<Slug> = rows.iter().map(|r| {
248+
let slug: String = r.get("slug");
249+
Slug { id: slug.clone(), slug: slug }
250+
}).collect();
251+
252+
#[derive(RustcEncodable)]
253+
struct R { category_slugs: Vec<Slug> }
254+
Ok(req.json(&R { category_slugs: slugs }))
255+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ pub fn middleware(app: Arc<App>) -> MiddlewareBuilder {
105105
api_router.get("/keywords/:keyword_id", C(keyword::show));
106106
api_router.get("/categories", C(category::index));
107107
api_router.get("/categories/:category_id", C(category::show));
108+
api_router.get("/category_slugs", C(category::slugs));
108109
api_router.get("/users/:user_id", C(user::show));
109110
let api_router = Arc::new(R404(api_router));
110111

0 commit comments

Comments
 (0)