Fastest Way to Go From Database Design to Working Forms?


Our app development is starting to ramp up and our team is looking to streamline boilerplate tasks. Right now, we’re focusing on minimizing the time from “conceive of new database entity” to “have fully working CRUD pages”.

I don’t have much direct Ruby on Rails experience, but I am thinking of the famous David Heinemeier Hansson intro to Ruby on Rails video ( where he’s generating CRUD pages so fast he can’t help but say “Whoops!” every few seconds. :smile:

So, I’m trying to reproduce that in Ember. Right now, here’s our workflow:

  • Do database design (I use DataNamic DeZign, an awesome tool, and this is pretty streamlined)
  • I convert my data model into SQL
  • We are using “database evolution scripts” so I paste the relevant SQL into a text file that gets version-controlled. I run a command (we use a tool called FlyWay) and all SQL files are executed in the proper order and our database is updated.

Our database is done. Now onto the backend / API world. We’re using Java plus Hibernate (the most popular ORM) and jOOQ (a DSL for writing SQL):

  • We use our IDE to auto-generate our model classes. (Soon, we plan to do this on the command line)
  • Then we write a simple controller at our API level so Ember has the right API endpoints it can call for CRUD. This isn’t automated, but it’s pretty easy.

All of that works fine so far, but now we move to the Ember world and it gets tedious…

  • We’re using ember-cli, so we generate a route with ember generate route myNewRoute. That gives us a route and a Handlebars template file.
  • Next, we edit the Handlebars template to add our form fields. I wrote a set of components so form fields can be easily added with a single line like this:

{{form-singleLineText fieldValue=name fieldName="name" label="Name" placeholder="e.g. Jimbo Jones" hint="Some text to help user undrestand this field" }}

  • These fields are auto-bound to the var specified in fieldValue and I get validation out of the box by defining a validations JSON in my controller. Those aren’t too bad, but I still have to manually assemble them on the page and manually create the controller.

  • Then we manually create the Ember Data model. This is a little tedious.

  • Finally, we wire up the form submission code. This is a little cumbersome because our submit function makes a call to some functions we inherit from a Mixin. For example:

      submitForm: function() {
      // Call the 'validate' function defined by the FormMixin to enforce any validations
      if ( this.controller.get('isValidForm') ) {
        // Trigger the nice loading animation
        // ...Submit the form via AJAX...

Thanks to Ember’s convention over configuration, the API calls are ready to go with no work, but it’s still a pain to wire up our submit function.

I suppose the workflow isn’t terrible. But it just seems like so many steps from the moment I add a new database entity to the CRUD being available in our app. I’m wondering if others use a similar workflow, or if there are better workflows / tools out there that can further accelerate this?



I’d take a look at ember-cli’s generators and blueprints. I haven’t used them myself, but if you have a standard set of processes per model, I think this would fit the bill to spit out all the necessary models/routes/controllers/templates/partials/tests in one go.


It’s funny, I use these very blueprints all the time since I’m using ember-cli. But your comment made me take a look at the latest docs and I didn’t realize you can define your own blueprints!

The one thing that would be extra nice would be to connect to the underlying database, look for a model of the same name (e.g. look for a “locations”) table, pull out the attributes, and auto-generate the Ember model’s attributes plus possibly template that includes Handlebars Helpers that generate form inputs, all automagically.

That seems like an achievable extension of the existing blueprints module; maybe if I find the time – and it doesn’t already exist – I’ll try to implement this.

@tylers, thanks for your response!