title: Using slugs in URL in CRUD in MEANJS
body: <p>I needed to use slugs in the URL instead of the article ID so I changed a couple of things in the articles example given by meanjs but I have a problem, I can list, view and edit, but I can't create new ones.
  I'm not familiar with the MEAN stack so it is very possible I have something very wrong in my modifications, but I can think a way of making it work.</p>
  
  <p>The slug is generated from the title when creating the article. I would wanted to be edited also but If I put the slug field to be edited as well, the edit feature stops working too...</p>
  
  <p>The code is from the 0.4 branch of meanjs using vertical modules.</p>
  
  <p>In the articles.client.service.js if I change:</p>
  
  <pre><code>angular.module('articles').factory('Articles', ['$resource',
      function($resource) {
          return $resource('api/articles/:articleSlug', {
              articleSlug: '@slug'
          }, {
              update: {
                  method: 'PUT'
              }
          });
      }
  ]);
  </code></pre>
  
  <p>for:</p>
  
  <pre><code>angular.module('articles').factory('Articles', ['$resource',
      function($resource) {
          return $resource('api/articles/:articleSlug', {
              articleSlug: '@_id'
          }, {
              update: {
                  method: 'PUT'
              }
          });
      }
  ]);
  </code></pre>
  
  <p>The create feature starts working, but the editing feature stops... -.-</p>
  
  <p>Any help would be appreciate. Thanks</p>
  
  <p>This is my <strong>articles.server.routes.js</strong></p>
  
  <pre><code>'use strict';
  
  /**
   * Module dependencies.
   */
  var articlesPolicy = require('../policies/articles.server.policy'),
      articles = require('../controllers/articles.server.controller');
  
  module.exports = function(app) {
      // Articles collection routes
      app.route('/api/articles').all(articlesPolicy.isAllowed)
          .get(articles.list)
          .post(articles.create);
  
      // Single article routes
      app.route('/api/articles/:articleSlug').all(articlesPolicy.isAllowed)
          .get(articles.read)
          .put(articles.update)
          .delete(articles.delete);
  
      // Finish by binding the article middleware
      app.param('articleSlug', articles.articleBySlug);
  };
  </code></pre>
  
  <p>This is my <strong>articles.client.service.js</strong></p>
  
  <pre><code>'use strict';
  
  //Articles service used for communicating with the articles REST endpoints
  angular.module('articles').factory('Articles', ['$resource',
      function($resource) {
          return $resource('api/articles/:articleSlug', {
              articleSlug: '@slug'
          }, {
              update: {
                  method: 'PUT'
              }
          });
      }
  ]);
  </code></pre>
  
  <p>This is my <strong>articles.client.controller.js</strong></p>
  
  <pre><code>'use strict';
  
  angular.module('articles').controller('ArticlesController', ['$scope', '$stateParams', '$location', 'Authentication', 'Articles',
      function($scope, $stateParams, $location, Authentication, Articles) {
          $scope.authentication = Authentication;
  
          $scope.create = function() {
              var article = new Articles({
                  slug: this.title.toLowerCase().replace(/ /g, '-'),
                  title: this.title,
                  content: this.content
              });
              article.$save(function(response) {
                  $location.path('articles/' + response.slug);
  
                  $scope.slug = '';
                  $scope.title = '';
                  $scope.content = '';
              }, function(errorResponse) {
                  $scope.error = errorResponse.data.message;
              });
          };
  
          $scope.remove = function(article) {
              if (article) {
                  article.$remove();
  
                  for (var i in $scope.articles) {
                      if ($scope.articles[i] === article) {
                          $scope.articles.splice(i, 1);
                      }
                  }
              } else {
                  $scope.article.$remove(function() {
                      $location.path('articles');
                  });
              }
          };
  
          $scope.update = function() {
              var article = $scope.article;
  
              article.$update(function() {
                  $location.path('articles/' + article.slug);
              }, function(errorResponse) {
                  $scope.error = errorResponse.data.message;
              });
          };
  
          $scope.find = function() {
              $scope.articles = Articles.query();
          };
  
          $scope.findOne = function() {
              $scope.article = Articles.get({
                  articleSlug: $stateParams.articleSlug
              });
          };
  
      }
  ]);
  </code></pre>
  
  <p>This is my <strong>articles.server.controller.js</strong></p>
  
  <pre><code>'use strict';
  
  /**
   * Module dependencies.
   */
  var _ = require('lodash'),
      path = require('path'),
      mongoose = require('mongoose'),
      Article = mongoose.model('Article'),
      errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller'));
  
  /**
   * Create a article
   */
  exports.create = function(req, res) {
      var article = new Article(req.body);
      article.user = req.user;
  
      article.save(function(err) {
          if (err) {
              return res.status(400).send({
                  message: errorHandler.getErrorMessage(err)
              });
          } else {
              res.json(article);
          }
      });
  };
  
  /**
   * Show the current article
   */
  exports.read = function(req, res) {
      res.json(req.article);
  };
  
  /**
   * Update a article
   */
  exports.update = function(req, res) {
      var article = req.article;
  
      article.title = req.body.title;
      article.content = req.body.content;
  
      article.save(function(err) {
          if (err) {
              return res.status(400).send({
                  message: errorHandler.getErrorMessage(err)
              });
          } else {
              res.json(article);
          }
      });
  };
  
  /**
   * Delete an article
   */
  exports.delete = function(req, res) {
      var article = req.article;
  
      article.remove(function(err) {
          if (err) {
              return res.status(400).send({
                  message: errorHandler.getErrorMessage(err)
              });
          } else {
              res.json(article);
          }
      });
  };
  
  /**
   * List of Articles
   */
  exports.list = function(req, res) {
      Article.find().sort('-created').populate('user', 'displayName').exec(function(err, articles) {
          if (err) {
              return res.status(400).send({
                  message: errorHandler.getErrorMessage(err)
              });
          } else {
              res.json(articles);
          }
      });
  };
  
  /**
   * Article middleware
   */
  
  exports.articleBySlug = function(req, res, next, slug) {
      Article.findOne({'slug': slug}).populate('user', 'displayName').exec(function(err, article) {
          if (err) return next(err);
          if (!article) return next(new Error('Failed to load article ' + slug));
          req.article = article;
          next();
      });
  };
  </code></pre>