The Making of a MVP

by Jess Brown

I've recently been wanting to create a mini series of videos on building MVP's. Most of my career I've been helping people take ideas and turn them into something real without a huge budget.

I've also really been into VueJs and have been wanting to explore and learn more about Webpack (via rails' webpacker) and rails and how to create a smooth workflow using these 3 tools together.

So, when I recently ran across this tweet by these two cool guys I know with, I thought, there's a good opportunity to put all these things together and so voila!

Want to skip to the end and see the final product?


Here's a quick intro on getting started:

Step 1 - Setup

I'm starting with a starter app I use that has some features alreay installed (authentication, oauth, authorization, etc)

Step 2 - Creating Contracts

In this step I create the backend data models and database tables, controllers and view templates as a starting point of creating contracts. This is pretty basic railsy stuff, however, one interesting point might be that I choose to use scaffolds (automaticly generated models, controllers, views) which is considered a bit amatuerish by many, but if you're building a javascript frontend anyway, you really only need a basic API to interact with. Also, it's nice that scaffolds come baked in with json views.

Step 3 - Setting up Vue

In this step, I show you how I use a custom rails generator to setup my VueJs single file component for managing the contracts. I also get into handling the GET request to fetch the contract and the PUT request to save the contract.

Step 4 - Adding Markdown

In this step, I show you how to convert our contract's markdown into html all in real time using showdown. This is also a really neat example of how to use webpack to add js libraries.

Step 5 - Adding Custom Fields

In this video, we make use of PostgreSQL's JSON data type and tie that into the Vue frontend to dynamically create multiple custom fields for our contract.

Step 5 - Populating Custom Fields - Part 1

In this video, we make use of PostgreSQL's JSON data type and tie that into the Vue frontend to dynamically create multiple custom fields for our contract. I split the videos into two parts because it got a little long as we get into the grit of parsing our custom fields and replacing with the custom fields' value.

It part 1, we extract the markdown rendering functionality into it's own component since we're introducing more logic and also anticipate reusing this functionality in other parts of the app.

Step 5 - Populating Custom Fields - Part 2

In part two, we get real detailed and add the computed property to filter the contract and replace the custom fields with values.

Step 6 - Duplicating & Deleting Contracts

In this video, I add some basic management features to our contracts.

Step 7 - Adding Alertify

In this video, I add a js library called alertifyjs to help with giving notifications when we save the contract. What's interesting about this video is learning how to use webpacker to add the library.

Step 8 - Adding a share token for sharing the contract

This video takes steps to add the ability to turn on sharing and when turned on, it generates a share token url (much like Google Drive or Dropbox).

Step 9 - Signng The Contract

It this video, we take the final steps to wrap up or MVP by adding the ability to share the URL and collect a signature.

Final Product

See a quick video on the final product and then checkout the live version.

Live version:

Or Hack on it:

Debug JS Comple Errors on Heroku

by Jess Brown

ExecJS::RuntimeError: SyntaxError: Unexpected token punc «,», expected punc «:» (line: 1559, col: 7, pos: 56557)

Recently ran into this issue on Heroku and found a a great answer on Stack Overflow I wanted to share how it works:

Here's the link to the Stack Overflow article:

Here's the one liner:

JS_PATH = "app/assets/javascripts/**/*.js"; Dir[JS_PATH].each{|file_name| puts "\n#{file_name}"; puts Uglifier.compile( }

Save rails console output to file on Heroku

by Jess Brown

The rails console was one of the parts of rails that I quickly fell in love with. Quickly being able to run your app's code and access the database from a CLI was very empowering.

If you're debugging code, checking data, or running impromptu reports, the rails console is your goto tool.

If you need to do something with the data you're querying from the console and it's a lot of data, you may wish to save it to a file and this can be not-so-straight forward on Heroku.

Checkout the below video and let me know what you think:

System time zone on local ruby

by Jess Brown

Most production servers will have a system time zone of UTC. For example on heroku:

$ heroku run rails c
Running rails c on ⬢ brownwebdesign... up, run.2977
Loading production environment (Rails 4.1.16)
=> 2017-07-11 12:45:33 +0000

Most local development environments will have a time zone of the system time zone. If your Mac's time is Eastern, your time will look like this:

$ rails c
Loading development environment (Rails 4.1.16)
[1] pry(main)>
=> 2017-07-11 08:46:52 -0400

This typically will not cause any issues because rails will convert time to UTC to store in database and then convert time to the set time zone configured in the app. Woring with time zones in your rails app is a whole other topic (checkout this article for some great tips).

However, I recently ran into an issue where I was using the Chronic gem to parse user inputed time and it uses the system ruby time. My devlopment results were not matching production results. I found a neat tip to easily make your local system ruby use UTC just like the production system: just set the TZ environment variable:

$ TZ=UTC rails s

## or ##

$ TZ=utc rails c
Loading development environment (Rails 4.1.16)
[1] pry(main)>
=> 2017-07-11 12:55:45 +0000

An alternative to bundle update

by Jess Brown

Bundle update can be the cause of a splitting headache. A lesser known fact is that when you run bundle update GEMNAME bundler will actually update GEMNAME and all of GEMNAME's dependencies. And this of course can lead to a much higher chance of conflicts.

Checkout the video to see what I mean:

Give this a try next time you need to 'update' a gem. For more detail, checkout this great explanation and more tips: