From b4d3eab02c88c941e506153545335cae07f0cb36 Mon Sep 17 00:00:00 2001 From: DC* Date: Thu, 14 Aug 2014 22:05:54 -0300 Subject: [PATCH] Heroku integration with foreman Add foreman configuration for Heroku: - To test production configuration execute NODE_ENV=production foreman start - Database connection configuration now handles "use_env_variable" which should be defined as a environment variable such as "DATABASE_URL" with a proper database URI connection string, ie: postgres://user:password@db.example.com:5432/database - Added package.json configuration to run migrations and db seed after `npm install` Update frontend models to match sequelize definition. Update views to work according to the changes above. Handling isCompleted and parentId apropiately for PostgreSQL databases --- config/database.json | 6 +---- config/production.json | 9 +------- orm.js | 19 ++++++++++++++++ package.json | 6 +++-- public/javascripts/models/task.js | 10 ++++---- public/javascripts/views/list.js | 4 ++-- public/javascripts/views/task.js | 38 +++++++++++++++---------------- public/templates/task.html | 4 ++-- server.js | 4 ++-- 9 files changed, 55 insertions(+), 45 deletions(-) diff --git a/config/database.json b/config/database.json index bd795be..8f6ec63 100644 --- a/config/database.json +++ b/config/database.json @@ -8,10 +8,6 @@ "storage": "db/test.sqlite" }, "production": { - "username": "postgres", - "password": "", - "database": "hackflowy", - "host" : "localhost", - "dialect" : "postgres" + "use_env_variable": "DATABASE_URL" } } diff --git a/config/production.json b/config/production.json index 4e7dd98..2abad20 100644 --- a/config/production.json +++ b/config/production.json @@ -1,13 +1,6 @@ { "port": 3000, "database": { - "username": "postgres", - "password": "", - "database": "hackflowy", - "options" : { - "dialect": "postgres", - "host" : "localhost", - "port" : "5432" - } + "use_env_variable": "DATABASE_URL" } } diff --git a/orm.js b/orm.js index f988d00..8a0d20b 100644 --- a/orm.js +++ b/orm.js @@ -1,7 +1,26 @@ var Sequelize = require('sequelize'); +/* http://sequelizejs.com/articles/heroku */ +var parseUrl = function(url) { + var match = url.match(/([\w]+):\/\/([^:]+):([^@]+)@([^:]+):(\d+)\/(.+)/); + db = { + database : match[6], + username : match[2], + password : match[3], + options : { + port : match[5], + host : match[4], + dialect : match[1], + } + } + return db; +} + module.exports = { configure: function(db) { + db.url = db.use_env_variable ? process.env[db.use_env_variable] : null; + db = db.url ? parseUrl(db.url) : db; return new Sequelize(db.database, db.username, db.password, db.options); } } + diff --git a/package.json b/package.json index 5a8b8b4..b12458b 100644 --- a/package.json +++ b/package.json @@ -5,12 +5,14 @@ "dependencies": { "express": "~3.1.0", "path": "~0.4.9", - "mysql": "~2.0.0", - "sqlite3": "~2.1.0", + "pg": "~3.4.1", "sequelize": "~1.7.9", "socket.io": "~1.0.6", "config": "~1.0.2" }, + "devDependencies": { + "sqlite3": "~2.1.0" + }, "engines": { "node": "0.10.x" }, diff --git a/public/javascripts/models/task.js b/public/javascripts/models/task.js index 23e141e..2fbf3c7 100644 --- a/public/javascripts/models/task.js +++ b/public/javascripts/models/task.js @@ -9,20 +9,20 @@ Backbone var TaskModel = Backbone.Model.extend({ defaults: { - parent_id: '', + parentId: 0, content: '', - is_completed:'n' + isCompleted: 0 }, toggelCompletedStatus:function(isCompleted){ var prev_isCompleted = isCompleted, self = this; - this.save({'is_completed':isCompleted}, + this.save({'isCompleted':isCompleted}, { success:function(){}, error:function(){ //REVERT BACK ON ERROR - self.set({'is_completed':prev_isCompleted}); + self.set({'isCompleted':prev_isCompleted}); } }) } @@ -31,4 +31,4 @@ Backbone return TaskModel; -}); \ No newline at end of file +}); diff --git a/public/javascripts/views/list.js b/public/javascripts/views/list.js index 2f7f608..c9eeed3 100644 --- a/public/javascripts/views/list.js +++ b/public/javascripts/views/list.js @@ -37,8 +37,8 @@ TaskView model: task }); var a = taskView.render(); - if (a.model.get('parent_id')!=0) - a.$el.insertAfter($('*[data-id="'+a.model.get('parent_id')+'"]').parents('li:first')); + if (a.model.get('parentId')!=0) + a.$el.insertAfter($('*[data-id="'+a.model.get('parentId')+'"]').parents('li:first')); else this.$el.append(a.el); } diff --git a/public/javascripts/views/task.js b/public/javascripts/views/task.js index d84e47f..a9ae278 100644 --- a/public/javascripts/views/task.js +++ b/public/javascripts/views/task.js @@ -38,7 +38,7 @@ taskTemplate var task = this; this.socket.on('task', function(data){ if (task.model.id == data.id) { - task.model.set({'content':data.content, 'is_completed':data.is_completed}); + task.model.set({'content':data.content, 'isCompleted':data.isCompleted}); } }); }, @@ -47,9 +47,9 @@ taskTemplate var tmpl = _.template(this.template); var task = this; this.$el.html(tmpl({model:this.model.toJSON()})); - if (this.model.get('parent_id')!=0) { + if (this.model.get('parentId')!=0) { this.$el.addClass('shift1'); - var className = $('*[data-id="'+this.model.get('parent_id')+'"]').parents('li:first').attr('class'); + var className = $('*[data-id="'+this.model.get('parentId')+'"]').parents('li:first').attr('class'); if (className!=undefined && className!=0 && className.substring(0,5) == 'shift') { this.$el.removeClass(); this.$el.addClass('shift' + (parseInt(className.charAt(5))+1)); @@ -74,31 +74,31 @@ taskTemplate if (e.shiftKey && e.keyCode == 9) { var model = this.$el.next('li').find('input').data('id'); model = Tasks.get(model); - var old_parent = model.get('parent_id'); + var old_parent = model.get('parentId'); old_parent = Tasks.get(old_parent); - var new_parent = old_parent.get('parent_id'); + var new_parent = old_parent.get('parentId'); if (new_parent == null) new_parent = 0; - model.set('parent_id',new_parent); - model.save({content: model.get('content'), parent_id: model.get('parent_id')}); + model.set('parentId',new_parent); + model.save({content: model.get('content'), parentId: model.get('parentId')}); } else if (e.keyCode == 9) { var parent = this.$el.prev('li').prev('li').find('input').data('id'); var current = this.$el.prev('li').find('input').data('id'); var model = Tasks.get(current); - model.set('parent_id',parent); - model.save({content: model.get('content'), parent_id: model.get('parent_id')}); + model.set('parentId',parent); + model.save({content: model.get('content'), parentId: model.get('parentId')}); } this.socket.emit('task', { id: this.model.id, - parent_id: this.model.parent_id, + parentId: this.model.parentId, content: this.$input.val().trim(), - is_completed:this.model.toJSON().is_completed + isCompleted:this.model.toJSON().isCompleted }); }, update: function(e) { if ( e.which === constants.ENTER_KEY ) { - Tasks.add({content:'', parent_id: this.model.get('parent_id')}); + Tasks.add({content:'', parentId: this.model.get('parentId')}); this.$input.blur(); this.$el.next('li').find('input').focus(); } @@ -110,7 +110,7 @@ taskTemplate this.model.destroy(); } else { - this.model.save({content: value, parent_id: this.model.attributes.parent_id}); + this.model.save({content: value, parentId: this.model.attributes.parentId}); } this.$el.removeClass('editing'); }, @@ -124,22 +124,22 @@ taskTemplate }, markComplete:function(){ - this.model.toggelCompletedStatus('Y'); + this.model.toggelCompletedStatus(true); this.socket.emit('task', { id: this.model.id, - parent_id: this.model.parent_id, + parentId: this.model.parentId, content:this.model.toJSON().content, - is_completed: this.model.toJSON().is_completed + isCompleted: this.model.toJSON().isCompleted }); }, unmarkComlete:function(){ - this.model.toggelCompletedStatus('N'); + this.model.toggelCompletedStatus(false); this.socket.emit('task', { id: this.model.id, - parent_id: this.model.parent_id, + parentId: this.model.parentId, content:this.model.toJSON().content, - is_completed: this.model.toJSON().is_completed + isCompleted: this.model.toJSON().isCompleted }); }, diff --git a/public/templates/task.html b/public/templates/task.html index 9b320ed..b15103b 100644 --- a/public/templates/task.html +++ b/public/templates/task.html @@ -4,7 +4,7 @@
- <% if(model.is_completed=='Y'){%> + <% if(model.isCompleted){%> Uncomplete
<%}else {%> Complete
@@ -16,7 +16,7 @@
- <% if(model.is_completed=='Y'){%> + <% if(model.isCompleted){%> <%}else {%> diff --git a/server.js b/server.js index 439d9b7..cda47f9 100644 --- a/server.js +++ b/server.js @@ -29,7 +29,7 @@ app.get('/tasks', function(req,res){ app.post('/tasks', function(req,res){ Tasks.create({ content: req.body.content, - parent: req.body.parent_id, + parent: parseInt(req.body.parent_id) || 0, isCompleted: false }).success(function(task){ res.send(task); @@ -40,7 +40,7 @@ app.put('/tasks/:id', function(req,res){ console.log(req.body.isCompleted); Tasks.find(req.params.id).success(function(task){ task.content = req.body.content; - task.isCompleted = req.body.isCompleted; + task.isCompleted = req.body.isCompleted == 1; task.save().success(function(task){ res.send(task); })