caboose-cms 0.5.5 → 0.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -103,6 +103,23 @@ module Caboose
103
103
  end
104
104
  render :json => options
105
105
  end
106
+
107
+ # GET /admin/categories/options
108
+ def admin_options
109
+ options = []
110
+ cat = Category.find(1)
111
+ cat.children.each do |c|
112
+ admin_options_helper(options, c, '')
113
+ end
114
+ render :json => options
115
+ end
116
+
117
+ def admin_options_helper(options, cat, prefix)
118
+ options << { :value => cat.id, :text => "#{prefix}#{cat.name}" }
119
+ cat.children.each do |c|
120
+ admin_options_helper(options, c, "#{prefix} - ")
121
+ end
122
+ end
106
123
  end
107
124
  end
108
125
 
@@ -295,6 +295,38 @@ module Caboose
295
295
  render :layout => 'caboose/admin'
296
296
  end
297
297
 
298
+ # GET /admin/products/json
299
+ def admin_json
300
+ return if !user_is_allowed('products', 'view')
301
+
302
+ # Temporary patch for vendor name sorting; Fix this
303
+ params[:sort] = 'store_vendors.name' if params[:sort] == 'vendor'
304
+
305
+ pager = Caboose::PageBarGenerator.new(params, {
306
+ 'vendor_name' => '',
307
+ 'search_like' => '',
308
+ 'price' => params[:filters] && params[:filters][:missing_prices] ? 0 : ''
309
+ }, {
310
+ 'model' => 'Caboose::Product',
311
+ 'sort' => 'title',
312
+ 'desc' => false,
313
+ 'base_url' => '/admin/products',
314
+ 'items_per_page' => 25,
315
+ 'use_url_params' => false,
316
+ 'abbreviations' => {
317
+ 'search_like' => 'store_products.title_concat_vendor_name_like'
318
+ },
319
+ 'includes' => {
320
+ 'vendor_name' => [ 'vendor' , 'name' ],
321
+ 'price' => [ 'variants' , 'price' ]
322
+ }
323
+ })
324
+ render :json => {
325
+ :pager => pager,
326
+ :models => pager.items.as_json(:includes => [:vendor, :categories])
327
+ }
328
+ end
329
+
298
330
  # GET /admin/products/add-upcs - TODO remove this; it's a temporary thing for woods-n-water
299
331
  def admin_add_upcs
300
332
  params[:vendor_id] if params[:vendor_id] and params[:vendor_id].empty?
@@ -312,7 +344,13 @@ module Caboose
312
344
 
313
345
  render :layout => 'caboose/admin'
314
346
  end
315
-
347
+
348
+ # GET /admin/products/:id/json
349
+ def admin_json_single
350
+ p = Product.find(params[:id])
351
+ render :json => p.as_json(:includes => [:vendor, :categories])
352
+ end
353
+
316
354
  # GET /admin/products/:id/general
317
355
  def admin_edit_general
318
356
  return if !user_is_allowed('products', 'edit')
@@ -533,43 +571,20 @@ module Caboose
533
571
  save = true
534
572
  params.each do |name,value|
535
573
  case name
536
- when 'alternate_id'
537
- product.alternate_id = value
538
- when 'date_available'
539
- if value.strip.length == 0
540
- product.date_available = nil
541
- else
542
- begin
543
- product.date_available = DateTime.parse(value)
544
- rescue
545
- resp.error = "Invalid date"
546
- save = false
547
- end
548
- end
549
- when 'title'
550
- product.title = value
551
- when 'caption'
552
- product.caption = value
553
- when 'featured'
554
- product.featured = value
555
- when 'description'
556
- product.description = value
557
- when 'category_id'
558
- product.category_id = value
559
- when 'vendor_id'
560
- product.vendor_id = value
561
- when 'handle'
562
- product.handle = value
563
- when 'seo_title'
564
- product.seo_title = value
565
- when 'seo_description'
566
- product.seo_description = value
567
- when 'option1'
568
- product.option1 = value
569
- when 'option2'
570
- product.option2 = value
571
- when 'option3'
572
- product.option3 = value
574
+ when 'alternate_id' then product.alternate_id = value
575
+ when 'title' then product.title = value
576
+ when 'caption' then product.caption = value
577
+ when 'featured' then product.featured = value
578
+ when 'description' then product.description = value
579
+ when 'vendor_id' then product.vendor_id = value
580
+ when 'handle' then product.handle = value
581
+ when 'seo_title' then product.seo_title = value
582
+ when 'seo_description' then product.seo_description = value
583
+ when 'status' then product.status = value
584
+ when 'category_id' then product.toggle_category(value[0], value[1])
585
+ when 'option1' then product.option1 = value
586
+ when 'option2' then product.option2 = value
587
+ when 'option3' then product.option3 = value
573
588
  when 'default1'
574
589
  product.default1 = value
575
590
  Variant.where(:product_id => product.id, :option1 => nil).each do |p|
@@ -587,9 +602,18 @@ module Caboose
587
602
  Variant.where(:product_id => product.id, :option3 => nil).each do |p|
588
603
  p.option3 = value
589
604
  p.save
605
+ end
606
+ when 'date_available'
607
+ if value.strip.length == 0
608
+ product.date_available = nil
609
+ else
610
+ begin
611
+ product.date_available = DateTime.parse(value)
612
+ rescue
613
+ resp.error = "Invalid date"
614
+ save = false
615
+ end
590
616
  end
591
- when 'status'
592
- product.status = value
593
617
  end
594
618
  end
595
619
  resp.success = save && product.save
@@ -141,5 +141,25 @@ module Caboose
141
141
  def option3_values
142
142
  self.variants.where(:status => 'Active').reorder(:option3_sort_order).pluck(:option3).uniq.reject { |x| x.nil? || x.empty? }
143
143
  end
144
+
145
+ def toggle_category(cat_id, value)
146
+ if value.to_i > 0 # Add to category
147
+ if cat_id == 'all'
148
+ CategoryMembership.where(:product_id => self.id).destroy_all
149
+ Category.reorder(:name).all.each{ |cat| CategoryMembership.create(:product_id => self.id, :category_id => cat.id) }
150
+ else
151
+ if !CategoryMembership.where(:product_id => self.id, :category_id => cat_id.to_i).exists?
152
+ CategoryMembership.create(:product_id => self.id, :category_id => cat_id.to_i)
153
+ end
154
+ end
155
+ else # Remove from category
156
+ if cat_id == 'all'
157
+ CategoryMembership.where(:product_id => self.id).destroy_all
158
+ else
159
+ CategoryMembership.where(:product_id => self.id, :category_id => cat_id.to_i).destroy_all
160
+ end
161
+ end
162
+ end
163
+
144
164
  end
145
165
  end
@@ -1,95 +1,87 @@
1
1
  <h1>Products</h1>
2
2
 
3
3
  <p style="margin: 12px 0">
4
- <a href="/admin/vendors/new">New Vendor</a>
5
- <span style="margin: 0 3px">|</span>
6
- <a href="/admin/products/new">New Product</a>
7
- <span style="margin: 0 3px">|</span>
8
- <a href="/admin/products/sort">Sort Products</a>
4
+ <a href="/admin/vendors/new">New Vendor</a><span style="margin: 0 3px">|</span>
5
+ <a href="/admin/products/new">New Product</a><span style="margin: 0 3px">|</span>
6
+ <a href="/admin/products/sort">Sort Products</a><span style="margin: 0 3px">|</span>
7
+ <a href='#'>Search Form</a>
9
8
  </p>
10
9
 
11
- <div class="media">
12
- <aside class="right">
13
- <form action="/admin/products" method="get" id="search_form" style="margin: 0 0 12px">
14
- <input type="text" name="search_like" placeholder="Title or Vendor Name" value="<%= params[:search_like] %>" style="width: 350px" />
15
- <input type="submit" value="Search" />
16
- <input type="button" value="Clear" onclick="window.location='/admin/products'" />
17
-
18
- <ul>
19
- <li><p>Find products that have:</p></li>
20
- <li><label><input name="filters[missing_prices]" type="checkbox" <%= 'checked="checked"' if params[:filters] && params[:filters][:missing_prices] %> /> Missing prices</label></li>
21
- <li><label><input name="filters[missing_images]" type="checkbox" <%= 'checked="checked"' if params[:filters] && params[:filters][:missing_images] %> /> Missing images</label></li>
22
- <li><label><input name="filters[no_vendor]" type="checkbox" <%= 'checked="checked"' if params[:filters] && params[:filters][:no_vendor] %> /> No vendor</label></li>
23
- </ul>
24
- </form>
25
- </aside>
10
+ <form action="/admin/products" method="get" id="search_form" style="margin: 0 0 12px">
11
+ <input type="text" name="search_like" placeholder="Title or Vendor Name" value="<%= params[:search_like] %>" style="width: 350px" />
12
+ <input type="submit" value="Search" />
13
+ <input type="button" value="Clear" onclick="window.location='/admin/products'" />
14
+ </form>
26
15
 
27
- <section>
28
- <% if @products.count > 0 %>
29
- <table class='data' id='properties_table'>
30
- <tr>
31
- <%= raw @gen.sortable_table_headings({
32
- 'id' => 'ID',
33
- 'title' => 'Title',
34
- 'vendor' => 'Vendor'
35
- }) %>
36
- </tr>
37
-
38
- <% @products.each do |p| %>
39
- <tr onclick="window.location='/admin/products/<%= p.id %>/general';">
40
- <td><%= raw p.id %></td>
41
- <td><%= raw p.title %></td>
42
- <td><%= raw p.vendor.nil? ? 'Unknown' : p.vendor.name %></td>
43
- </tr>
44
- <% end %>
45
- </table>
46
-
47
- <p><%= raw @gen.generate %></p>
48
- <% else %>
49
- <p>There are no products right now.</p>
50
- <% end %>
51
- </section>
52
- </div>
16
+ <div id='products'></div>
53
17
 
54
- <% content_for :caboose_css do %>
55
- <style>
56
- ul {
57
- list-style-type: none;
58
- padding: 0;
59
- }
60
- input[type=checkbox] {
61
- height: 16px;
62
- left: auto !important;
63
- margin: 0 0 12px !important;
64
- position: relative !important;
65
- top: auto !important;
66
- }
67
- label { cursor: pointer; }
68
- label input[type=checkbox] {
69
- height: 15px !important;
70
- left: auto !important;
71
- margin: 12px 0 !important;
72
- position: relative !important;
73
- top: auto !important;
74
- }
75
-
76
- .media,
77
- .media > section { overflow: hidden; }
78
- .media > aside {
79
- float: left;
80
- margin-right: 12px;
81
- }
82
- .media > aside.right {
83
- float: right;
84
- margin-left: 12px;
85
- }
86
- </style>
18
+ <% content_for :caboose_js do %>
19
+ <%= javascript_include_tag 'caboose/model/all' %>
20
+ <script type='text/javascript'>
21
+
22
+ $(document).ready(function() {
23
+ var that = this;
24
+ var table = new IndexTable({
25
+ form_authenticity_token: '<%= form_authenticity_token %>',
26
+ container: 'products',
27
+ base_url: '/admin/products',
28
+ allow_bulk_edit: false,
29
+ allow_bulk_delete: false,
30
+ allow_duplicate: false,
31
+ fields: [
32
+ { show: true , name: 'id' , nice_name: 'ID' , sort: 'id' , type: 'text' , value: function(p) { return p.id }, width: 500, editable: false },
33
+ { show: true , name: 'title' , nice_name: 'Title' , sort: 'title' , type: 'text' , value: function(p) { return p.title }, width: 200 },
34
+ { show: true , name: 'caption' , nice_name: 'Caption' , sort: 'caption' , type: 'text' , value: function(p) { return p.caption }, width: 200 },
35
+ { show: true , name: 'status' , nice_name: 'Status' , sort: 'status' , type: 'select' , value: function(p) { return p.status }, width: 200, options_url: '/admin/products/status-options' },
36
+ { show: true , name: 'handle' , nice_name: 'URL Handle' , sort: 'handle' , type: 'text' , value: function(p) { return p.handle }, width: 200 },
37
+ { show: true , name: 'seo_title' , nice_name: 'SEO Page Title' , sort: 'seo_title' , type: 'text' , value: function(p) { return p.seo_title }, width: 200 },
38
+ { show: false, name: 'seo_description' , nice_name: 'SEO Meta Description' , sort: 'seo_description' , type: 'textarea' , value: function(p) { return p.seo_description }, width: 200, height: 150 },
39
+ { show: true , name: 'alternate_id' , nice_name: 'Alternate ID' , sort: 'alternate_id' , type: 'text' , value: function(p) { return p.alternate_id }, width: 200 },
40
+ { show: true , name: 'date_available' , nice_name: 'Date Available' , sort: 'date_available' , type: 'date' , value: function(p) { return p.date_available }, width: 200 },
41
+ { show: false, name: 'featured' , nice_name: 'Featured' , sort: 'featured' , type: 'checkbox' , value: function(p) { return p.featured }, width: 200 },
42
+ { show: false, name: 'category_id' , nice_name: 'Categories' , sort: 'categories.name' , type: 'checkbox-multiple' , value: function(p) { return p.categories ? p.categories.map(function(c) { return c.id }) : []; }, text: function(p) { return p.categories ? p.categories.map(function(c) { return c.name }).join(', ') : ''; }, width: 200, height: 200, options_url: '/admin/categories/options' },
43
+ ],
44
+ new_model_text: 'New Product',
45
+ new_model_fields: [
46
+ { name: 'name', nice_name: 'Name', type: 'text', width: 400 }
47
+ ],
48
+ });
49
+ });
50
+
51
+ </script>
87
52
  <% end %>
88
53
 
89
- <% content_for :caboose_js do %>
90
- <script type='text/javascript'>
91
- $(document).ready(function() {
92
- var modal = new CabooseModal(800);
93
- });
94
- </script>
54
+ <% content_for :caboose_css do %>
55
+ <style>
56
+ ul {
57
+ list-style-type: none;
58
+ padding: 0;
59
+ }
60
+ input[type=checkbox] {
61
+ height: 16px;
62
+ left: auto !important;
63
+ margin: 0 0 12px !important;
64
+ position: relative !important;
65
+ top: auto !important;
66
+ }
67
+ label { cursor: pointer; }
68
+ label input[type=checkbox] {
69
+ height: 15px !important;
70
+ left: auto !important;
71
+ margin: 12px 0 !important;
72
+ position: relative !important;
73
+ top: auto !important;
74
+ }
75
+
76
+ .media,
77
+ .media > section { overflow: hidden; }
78
+ .media > aside {
79
+ float: left;
80
+ margin-right: 12px;
81
+ }
82
+ .media > aside.right {
83
+ float: right;
84
+ margin-left: 12px;
85
+ }
86
+ </style>
95
87
  <% end %>
data/config/routes.rb CHANGED
@@ -50,7 +50,7 @@ Caboose::Engine.routes.draw do
50
50
  post "admin/users/import" => "users#import"
51
51
  get "admin/users/:id/su" => "users#admin_su"
52
52
  get "admin/users/:id/edit-password" => "users#edit_password"
53
- get "admin/users/:id/edit" => "users#edit"
53
+ get "admin/users/:id" => "users#edit"
54
54
  put "admin/users/:id" => "users#update"
55
55
  post "admin/users" => "users#create"
56
56
  delete "admin/users/:id" => "users#destroy"
@@ -61,7 +61,7 @@ Caboose::Engine.routes.draw do
61
61
  get "admin/roles" => "roles#index"
62
62
  get "admin/roles/options" => "roles#options"
63
63
  get "admin/roles/new" => "roles#new"
64
- get "admin/roles/:id/edit" => "roles#edit"
64
+ get "admin/roles/:id" => "roles#edit"
65
65
  put "admin/roles/:id" => "roles#update"
66
66
  post "admin/roles" => "roles#create"
67
67
  delete "admin/roles/:id" => "roles#destroy"
@@ -89,7 +89,7 @@ Caboose::Engine.routes.draw do
89
89
  get "admin/permissions" => "permissions#index"
90
90
  get "admin/permissions/options" => "permissions#options"
91
91
  get "admin/permissions/new" => "permissions#new"
92
- get "admin/permissions/:id/edit" => "permissions#edit"
92
+ get "admin/permissions/:id" => "permissions#edit"
93
93
  put "admin/permissions/:id" => "permissions#update"
94
94
  post "admin/permissions" => "permissions#create"
95
95
  delete "admin/permissions/:id" => "permissions#destroy"
@@ -97,7 +97,7 @@ Caboose::Engine.routes.draw do
97
97
  get "admin/settings" => "settings#index"
98
98
  get "admin/settings/options" => "settings#options"
99
99
  get "admin/settings/new" => "settings#new"
100
- get "admin/settings/:id/edit" => "settings#edit"
100
+ get "admin/settings/:id" => "settings#edit"
101
101
  put "admin/settings/:id" => "settings#update"
102
102
  post "admin/settings" => "settings#create"
103
103
  delete "admin/settings/:id" => "settings#destroy"
@@ -112,8 +112,7 @@ Caboose::Engine.routes.draw do
112
112
  get "admin/pages/:id/block-options" => "pages#admin_block_options"
113
113
  get "admin/pages/:id/uri" => "pages#admin_page_uri"
114
114
  get "admin/pages/:id/delete" => "pages#admin_delete_form"
115
- get "admin/pages/:id/sitemap" => "pages#admin_sitemap"
116
- get "admin/pages/:id/edit" => "pages#admin_edit_general"
115
+ get "admin/pages/:id/sitemap" => "pages#admin_sitemap"
117
116
  get "admin/pages/:id/permissions" => "pages#admin_edit_permissions"
118
117
  get "admin/pages/:id/css" => "pages#admin_edit_css"
119
118
  get "admin/pages/:id/js" => "pages#admin_edit_js"
@@ -127,7 +126,8 @@ Caboose::Engine.routes.draw do
127
126
  get "admin/pages/:id/layout" => "pages#admin_edit_layout"
128
127
  put "admin/pages/:id/layout" => "pages#admin_update_layout"
129
128
  put "admin/pages/:id/viewers" => "pages#admin_update_viewers"
130
- put "admin/pages/:id/editors" => "pages#admin_update_editors"
129
+ put "admin/pages/:id/editors" => "pages#admin_update_editors"
130
+ get "admin/pages/:id" => "pages#admin_edit_general"
131
131
  put "admin/pages/:id" => "pages#admin_update"
132
132
  get "admin/pages" => "pages#admin_index"
133
133
  post "admin/pages" => "pages#admin_create"
@@ -283,12 +283,12 @@ Caboose::Engine.routes.draw do
283
283
 
284
284
  get '/admin/products/add-upcs' => 'products#admin_add_upcs'
285
285
 
286
- get '/admin/vendors' => 'vendors#admin_index'
287
- get '/admin/vendors/status-options' => 'vendors#status_options'
286
+ get '/admin/vendors/status-options' => 'vendors#status_options'
288
287
  get '/admin/vendors/new' => 'vendors#admin_new'
289
- get '/admin/vendors/:id/edit' => 'vendors#admin_edit'
290
- post '/admin/vendors/create' => 'vendors#admin_create'
291
- put '/admin/vendors/:id/update' => 'vendors#admin_update'
288
+ get '/admin/vendors/:id' => 'vendors#admin_edit'
289
+ put '/admin/vendors/:id' => 'vendors#admin_update'
290
+ post '/admin/vendors' => 'vendors#admin_add'
291
+ get '/admin/vendors' => 'vendors#admin_index'
292
292
 
293
293
  # Orders
294
294
 
@@ -298,35 +298,38 @@ Caboose::Engine.routes.draw do
298
298
 
299
299
  post "/reviews/add" => "reviews#add"
300
300
 
301
- get "/admin/products" => "products#admin_index"
302
- get '/admin/products/sort' => 'products#admin_sort'
303
- put '/admin/products/update-sort-order' => 'products#admin_update_sort_order'
304
- put "/admin/products/update-vendor-status/:id" => "products#admin_update_vendor_status"
305
- get "/admin/products/new" => "products#admin_new"
306
- get "/admin/products/status-options" => "products#admin_status_options"
307
- get "/admin/products/:id/general" => "products#admin_edit_general"
308
- get "/admin/products/:id/description" => "products#admin_edit_description"
309
- get "/admin/products/:id/categories" => "products#admin_edit_categories"
310
- post "/admin/products/:id/categories" => "products#admin_add_to_category"
311
- delete "/admin/products/:id/categories/:category_id" => "products#admin_remove_from_category"
312
- get "/admin/products/:id/variants" => "products#admin_edit_variants"
313
- get "/admin/products/:id/variants/json" => "products#admin_variants_json"
314
- get "/admin/products/:id/variant-cols" => "products#admin_edit_variant_columns"
315
- put "/admin/products/:id/variant-cols" => "products#admin_update_variant_columns"
316
- get "/admin/products/:id/variants/sort-order" => "products#admin_edit_variant_sort_order"
301
+ get "/admin/products" => "products#admin_index"
302
+ get "/admin/products/json" => "products#admin_json"
303
+ get '/admin/products/sort' => 'products#admin_sort'
304
+ put '/admin/products/update-sort-order' => 'products#admin_update_sort_order'
305
+ put "/admin/products/update-vendor-status/:id" => "products#admin_update_vendor_status"
306
+ get "/admin/products/new" => "products#admin_new"
307
+ get "/admin/products/status-options" => "products#admin_status_options"
308
+ get "/admin/products/:id/general" => "products#admin_edit_general"
309
+ get "/admin/products/:id/description" => "products#admin_edit_description"
310
+ get "/admin/products/:id/categories" => "products#admin_edit_categories"
311
+ post "/admin/products/:id/categories" => "products#admin_add_to_category"
312
+ delete "/admin/products/:id/categories/:category_id" => "products#admin_remove_from_category"
313
+ get "/admin/products/:id/variants" => "products#admin_edit_variants"
314
+ get "/admin/products/:id/variants/json" => "products#admin_variants_json"
315
+ get "/admin/products/:id/variant-cols" => "products#admin_edit_variant_columns"
316
+ put "/admin/products/:id/variant-cols" => "products#admin_update_variant_columns"
317
+ get "/admin/products/:id/variants/sort-order" => "products#admin_edit_variant_sort_order"
317
318
  put '/admin/products/:id/variants/option1-sort-order' => 'products#admin_update_variant_option1_sort_order'
318
319
  put '/admin/products/:id/variants/option2-sort-order' => 'products#admin_update_variant_option2_sort_order'
319
320
  put '/admin/products/:id/variants/option3-sort-order' => 'products#admin_update_variant_option3_sort_order'
320
- get "/admin/products/:id/images" => "products#admin_edit_images"
321
- post "/admin/products/:id/images" => "products#admin_add_image"
322
- get "/admin/products/:id/collections" => "products#admin_edit_collections"
323
- get "/admin/products/:id/seo" => "products#admin_edit_seo"
324
- get "/admin/products/:id/options" => "products#admin_edit_options"
325
- get "/admin/products/:id/delete" => "products#admin_delete_form"
326
- put "/admin/products/:id" => "products#admin_update"
327
- post "/admin/products" => "products#admin_add"
328
- delete "/admin/products/:id" => "products#admin_delete"
329
- put "/admin/products/:id/update-vendor" => "products#admin_update_vendor"
321
+ get "/admin/products/:id/images" => "products#admin_edit_images"
322
+ post "/admin/products/:id/images" => "products#admin_add_image"
323
+ get "/admin/products/:id/collections" => "products#admin_edit_collections"
324
+ get "/admin/products/:id/seo" => "products#admin_edit_seo"
325
+ get "/admin/products/:id/options" => "products#admin_edit_options"
326
+ get "/admin/products/:id/delete" => "products#admin_delete_form"
327
+ get "/admin/products/:id/json" => "products#admin_json_single"
328
+ get "/admin/products/:id" => "products#admin_edit_general"
329
+ put "/admin/products/:id" => "products#admin_update"
330
+ post "/admin/products" => "products#admin_add"
331
+ delete "/admin/products/:id" => "products#admin_delete"
332
+ put "/admin/products/:id/update-vendor" => "products#admin_update_vendor"
330
333
 
331
334
  get "/admin/products/:product_id/variants/:variant_id/edit" => "variants#admin_edit"
332
335
  get "/admin/variants/status-options" => "variants#admin_status_options"
@@ -341,7 +344,7 @@ Caboose::Engine.routes.draw do
341
344
  get "/admin/categories" => "categories#admin_index"
342
345
  get "/admin/categories/new" => "categories#admin_new"
343
346
  get "/admin/categories/options" => "categories#admin_options"
344
- get "/admin/categories/:id/edit" => "categories#admin_edit"
347
+ get "/admin/categories/:id" => "categories#admin_edit"
345
348
  put "/admin/categories/:id" => "categories#admin_update"
346
349
  get '/admin/categories/status-options' => 'categories#admin_status_options'
347
350
  post "/admin/categories/:id" => "categories#admin_update"