Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Mura ORM and EmberJS
• By Matt Levine

Who Am I?
Who Am I?
• CTO of Blue River Interactive Group
Who Am I?
• CTO of Blue River Interactive Group

• Started Mura CMS with Sean Schoeder a long time
ago...
What We’re Talking About
What We’re Talking About
• Mura ORM
What We’re Talking About
• Mura ORM

• EmberJS
What We’re Talking About
• Mura ORM

• EmberJS

• But Mostly Mura ORM
Why Mura ORM?
Why Mura ORM?
• It all started with creating the Mura approval chains.
Why Mura ORM?
• It all started with creating the new Mura approval
chains.

• Needed to create 5 new entities and didn’t w...
Started with 3 Options
Started with 3 Options
• Custom DAOs
Custom DAOs
• Too much work
Custom DAOs
• Too much work

• No code re-use
Started with 3 Options
• Custom DAOs

• Mura Class Extension Module
Mura Class Extension Module
GREAT FOR: 

• Targeting nodes for custom business logic
Mura Class Extension Module
GREAT FOR: 

• Targeting nodes for custom business logic

• Rendering events
Mura Class Extension Module
GREAT FOR: 

• Targeting nodes for custom business logic

• Rendering events

• Data events
Mura Class Extension Module
GREAT FOR: 

• Targeting nodes for custom business logic

• Rendering events

• Data events

•...
Mura Class Extension Module
NOT AS GOOD FOR: 

• Maintaining relationships between entities
Mura Class Extension Module
NOT AS GOOD FOR: 

• Maintaining relationships between entities

• Really custom business logic
Mura Class Extension Module
NOT AS GOOD FOR: 

• Maintaining relationships between entities

• Really custom business logi...
Mura Class Extension Module
RECAP:

• Only handles very simple entities
Mura Class Extension Module
RECAP:

• Only handles very simple entities

• Great for hooking attributes to existing Mura e...
Mura Class Extension Module
RECAP:

• Only handles very simple entities

• Great for hooking attributes to existing Mura e...
Mura Class Extension Module
RECAP:

• Only handles very simple entities

• Great for hooking attributes to existing Mura e...
Started with 3 Options
• Custom DAOs

• Mura Class Extension Module

• CF based Hibernate ORM
CF Hibernate ORM
GREAT FOR:

•Easily defining entity properties
CF Hibernate ORM
GREAT FOR:

•Easily defining entity properties

•CRUD operations
CF Hibernate ORM
GREAT FOR:

•Easily defining entity properties

•CRUD operations

•Managing relationships to other CF ORM...
CF Hibernate ORM
GREAT FOR:

•Easily defining entity properties

•CRUD operations

•Managing relationships to other CF ORM...
CF Hibernate ORM
NOT SO GOOD FOR:

•Creating relationships to Mura core entites
CF Hibernate ORM
NOT SO GOOD FOR:

•Creating relationships to Mura core entites

•Working with DI1
CF Hibernate ORM
NOT SO GOOD FOR:

•Creating relationships to Mura core entites

•Working with DI1

•Don’t want to deal wi...
CF Hibernate ORM
NOT SO GOOD FOR:

•Creating relationships to Mura core entites

•Working with DI1

•Don’t want to deal wi...
CF Hibernate ORM
RECAP:

•Love the concept!
CF Hibernate ORM
RECAP:

•Love the concept!

•Seems like CF ORM would be a walled garden.
CF Hibernate ORM
RECAP:

•Love the concept!

•Seems like CF ORM would be a walled garden.

•Sharing a ORM session with oth...
CF Hibernate ORM
RECAP:

•Love the concept!

•Seems like CF ORM would be a walled garden.

•Sharing a ORM session with oth...
CF Hibernate ORM
RECAP:

•When things go wrong it really feels like a black box. You
get low level java error that don't n...
What if?
What if?
• I roll my own that works exactly how Mura works!
I Could Make Them
Accesible via $.getBean(entityName); 
and
application.serviceFactory(entityName);

Takes advantage of DI...
Have the Same Interactions
• entity.loadBy()

• entity.get{relateEntity}Iterator();

• entity.get{relateEntity}Query();

•...
Have the Same Interactions
• entityFeed.addParam();

• entityFeed.getQuery();

• entityFeed.getIterator();
Have the Same Interactions
feed=$.getBean(entityName).getFeed();

feed.addParam(column=’mycolumn’,criteria=‘test’);

itera...
Be Targetable By Mura Events
component extends=”mura.cfobject”{

onBeforeMyEntitySave($){

var bean=$.event(‘bean’);

.......
They Could Also
• Know how to bundle themselves

• Play well with Mura content versioning

• Have a more simple implementa...
It could use the same
component attributes
• entityName

• table

• datasource

• discriminatorColumn

• discriminatorValu...
With some new ones
• bundleable

• cacheName

• dbtype

• manageSchema

• useTrash
It could use the same property
attributes
• name

• persistent

• fieldtype

• cfc

• fkcolumn

• type

• cascade

• singu...
With some new ones
• dataType

• nullable

• required

• validate

• message

• regex

• comparable
And a bunch attributes for
validation
• minValue

• maxValue

• minLength

• maxLength

• minCollection

• maxCollection

...
It could also support CF ORM
• preLoad();

• postLoad();

• preUpdate();

• postUpdate();

• preCreate();
• postCreate();
...
So that’s what we did
So that’s what we did
• Now let’s actually see some code
EmberJS
EmberJS
• A Framework for Creating 



Ambitious Web Applications
EmberJS
• A Framework for Creating 



Ambitious Web Applications

• A Client Side MVC Framework
EmberJS
• A Framework for Creating 



Ambitious Web Applications

• A Client Side MVC Framework

• That’s opinionated in ...
EmberJS
• A Framework for Creating 



Ambitious Web Applications

• A Client Side MVC Framework

• That’s opinionated in ...
EmberJS
• A Framework for Creating 



Ambitious Web Applications

• A Client Side MVC Framework

• That’s opinionated in ...
Handlebar.JS
<div>

<label>Name:</label>

{{input type="text" value=name placeholder="Enter your
name"}}

</div>

<div cla...
Ember-Data
•A Data Persistence Library for Ember.js
Ember-Data
•A Data Persistence Library for Ember.js

•We’ve created a Mura ORM Adapter for Ember-Data
Ember-Data
•A Data Persistence Library for Ember.js

•We’ve created a Mura ORM Adapter for Ember-Data

•Sooo…
Ember-Data
component extends="mura.bean.beanORM" 

entityName="widget" table="widgets" {

property name="widgetid" fieldty...
Ember-Data
App.Widget = DS.Model.extend({

primaryKey: 'widgetid',

widgetid: DS.attr(),

siteid: DS.attr(),

name: DS.att...
Ember-Data
component extends="mura.bean.beanORM"
entityName="option" table="widgetoptions" {

property name="optionid" fie...
Ember-Data
App.Option = DS.Model.extend({

primaryKey: 'optionid',

optionid: DS.attr(),

siteid: DS.attr(),

name: DS.att...
Ember-Data
App.WidgetRoute = Ember.Route.extend({

model: function(params) {

return this.store.find(‘Widget’,params.widge...
Ember-Data
<script type="text/x-handlebars" id=“widget">

<h3>{{name}} ({{options.length}})</h3>

{{#if options.length}}

...
Ember.js
•We’re currently prototyping an Ember.js based front
for Mura
Ember.js
•We’re currently prototyping an Ember.js based front
for Mura

•It will allow Mura to run as a service
Ember.js
•We’re currently prototyping an Ember.js based front
for Mura

•It will allow Mura to run as a service

•This wil...
Ember.js
•We’re currently prototyping an Ember.js based front
for Mura

•It will allow Mura to run as a service

•This wil...
Upcoming SlideShare
Loading in …5
×

Mura ORM & Ember JS

1,041 views

Published on

Originally presented by Matt Levine at MuraCon EU 2014 in Edinburgh, Scotland.

Published in: Technology, Education
  • Be the first to comment

  • Be the first to like this

Mura ORM & Ember JS

  1. 1. Mura ORM and EmberJS • By Matt Levine

  2. 2. Who Am I?
  3. 3. Who Am I? • CTO of Blue River Interactive Group
  4. 4. Who Am I? • CTO of Blue River Interactive Group • Started Mura CMS with Sean Schoeder a long time ago...
  5. 5. What We’re Talking About
  6. 6. What We’re Talking About • Mura ORM
  7. 7. What We’re Talking About • Mura ORM • EmberJS
  8. 8. What We’re Talking About • Mura ORM • EmberJS • But Mostly Mura ORM
  9. 9. Why Mura ORM?
  10. 10. Why Mura ORM? • It all started with creating the Mura approval chains.
  11. 11. Why Mura ORM? • It all started with creating the new Mura approval chains. • Needed to create 5 new entities and didn’t want to write a custom DAO for each one.
  12. 12. Started with 3 Options
  13. 13. Started with 3 Options • Custom DAOs
  14. 14. Custom DAOs • Too much work
  15. 15. Custom DAOs • Too much work • No code re-use
  16. 16. Started with 3 Options • Custom DAOs • Mura Class Extension Module
  17. 17. Mura Class Extension Module GREAT FOR: • Targeting nodes for custom business logic
  18. 18. Mura Class Extension Module GREAT FOR: • Targeting nodes for custom business logic • Rendering events
  19. 19. Mura Class Extension Module GREAT FOR: • Targeting nodes for custom business logic • Rendering events • Data events
  20. 20. Mura Class Extension Module GREAT FOR: • Targeting nodes for custom business logic • Rendering events • Data events • Adding custom values to be used within rendering and data events
  21. 21. Mura Class Extension Module NOT AS GOOD FOR: • Maintaining relationships between entities
  22. 22. Mura Class Extension Module NOT AS GOOD FOR: • Maintaining relationships between entities • Really custom business logic
  23. 23. Mura Class Extension Module NOT AS GOOD FOR: • Maintaining relationships between entities • Really custom business logic • Directly querying the database
  24. 24. Mura Class Extension Module RECAP: • Only handles very simple entities
  25. 25. Mura Class Extension Module RECAP: • Only handles very simple entities • Great for hooking attributes to existing Mura entities, but bad for complicated logic.
  26. 26. Mura Class Extension Module RECAP: • Only handles very simple entities • Great for hooking attributes to existing Mura entities, but bad for complicated logic. • Want the data to be stored in flat tables.
  27. 27. Mura Class Extension Module RECAP: • Only handles very simple entities • Great for hooking attributes to existing Mura entities, but bad for complicated logic. • Want the data to be stored in flat tables. • Not the appropriate choice
  28. 28. Started with 3 Options • Custom DAOs • Mura Class Extension Module • CF based Hibernate ORM
  29. 29. CF Hibernate ORM GREAT FOR: •Easily defining entity properties
  30. 30. CF Hibernate ORM GREAT FOR: •Easily defining entity properties •CRUD operations
  31. 31. CF Hibernate ORM GREAT FOR: •Easily defining entity properties •CRUD operations •Managing relationships to other CF ORM entities
  32. 32. CF Hibernate ORM GREAT FOR: •Easily defining entity properties •CRUD operations •Managing relationships to other CF ORM entities •You just describe the entity with properties and start using it!
  33. 33. CF Hibernate ORM NOT SO GOOD FOR: •Creating relationships to Mura core entites
  34. 34. CF Hibernate ORM NOT SO GOOD FOR: •Creating relationships to Mura core entites •Working with DI1
  35. 35. CF Hibernate ORM NOT SO GOOD FOR: •Creating relationships to Mura core entites •Working with DI1 •Don’t want to deal with sharing hibernate sessions with other application and plugins
  36. 36. CF Hibernate ORM NOT SO GOOD FOR: •Creating relationships to Mura core entites •Working with DI1 •Don’t want to deal with sharing hibernate sessions with other application and plugins •It just works, but when it doesn't... Good Luck
  37. 37. CF Hibernate ORM RECAP: •Love the concept!
  38. 38. CF Hibernate ORM RECAP: •Love the concept! •Seems like CF ORM would be a walled garden.
  39. 39. CF Hibernate ORM RECAP: •Love the concept! •Seems like CF ORM would be a walled garden. •Sharing a ORM session with other sub applications sounds like a nightmare
  40. 40. CF Hibernate ORM RECAP: •Love the concept! •Seems like CF ORM would be a walled garden. •Sharing a ORM session with other sub applications sounds like a nightmare •I would like the relationships to be based on DI1 BeanName or Alias rather than component path.
  41. 41. CF Hibernate ORM RECAP: •When things go wrong it really feels like a black box. You get low level java error that don't neccesarilly easily map to what you did wrong in your CFML •CF ORM really seems to want you to forget about sql and just go through it's black box. I like sql. I think is it's pretty darn cool
  42. 42. What if?
  43. 43. What if? • I roll my own that works exactly how Mura works!
  44. 44. I Could Make Them Accesible via $.getBean(entityName); 
and application.serviceFactory(entityName); Takes advantage of DI1 dependency injection
  45. 45. Have the Same Interactions • entity.loadBy() • entity.get{relateEntity}Iterator(); • entity.get{relateEntity}Query(); • entity.get{relateEntity}(); • entity.getFeed(); • entity.validate(); • entity.getError();
  46. 46. Have the Same Interactions • entityFeed.addParam(); • entityFeed.getQuery(); • entityFeed.getIterator();
  47. 47. Have the Same Interactions feed=$.getBean(entityName).getFeed(); feed.addParam(column=’mycolumn’,criteria=‘test’); iterator=feed.getIterator(); ! <cfloop condition=”iterator.hasNext()”> <cfoutput>#iterator.next().getMyColumn()#</cfoutput> </cfloop>
  48. 48. Be Targetable By Mura Events component extends=”mura.cfobject”{ onBeforeMyEntitySave($){ var bean=$.event(‘bean’); .... } }
  49. 49. They Could Also • Know how to bundle themselves • Play well with Mura content versioning • Have a more simple implementation than CF ORM
  50. 50. It could use the same component attributes • entityName • table • datasource • discriminatorColumn • discriminatorValue
 • orderby • readonly
  51. 51. With some new ones • bundleable • cacheName • dbtype • manageSchema • useTrash
  52. 52. It could use the same property attributes • name • persistent • fieldtype • cfc • fkcolumn
 • type • cascade • singularName • orderby • length • default • ormType ! !
  53. 53. With some new ones • dataType • nullable • required • validate • message
 • regex • comparable
  54. 54. And a bunch attributes for validation • minValue • maxValue • minLength • maxLength • minCollection
 • maxCollection • minList • maxList • inList • method • lte • lt • gte • gt • eq • neq
  55. 55. It could also support CF ORM • preLoad(); • postLoad(); • preUpdate(); • postUpdate(); • preCreate(); • postCreate(); • postInsert(); • preDelete(); • postDelete();
  56. 56. So that’s what we did
  57. 57. So that’s what we did • Now let’s actually see some code
  58. 58. EmberJS
  59. 59. EmberJS • A Framework for Creating 



Ambitious Web Applications
  60. 60. EmberJS • A Framework for Creating 



Ambitious Web Applications • A Client Side MVC Framework
  61. 61. EmberJS • A Framework for Creating 



Ambitious Web Applications • A Client Side MVC Framework • That’s opinionated in a good way
  62. 62. EmberJS • A Framework for Creating 



Ambitious Web Applications • A Client Side MVC Framework • That’s opinionated in a good way • So that your application is developed in a consistent way which enables easier scalability
  63. 63. EmberJS • A Framework for Creating 



Ambitious Web Applications • A Client Side MVC Framework • That’s opinionated in a good way • So that your application is developed in a consistent way which enables easier scalability • Utilizes Handlebars.js for easy templating
  64. 64. Handlebar.JS <div> <label>Name:</label> {{input type="text" value=name placeholder="Enter your name"}} </div> <div class="text"> <h1>My name is {{name}} and I want to learn Ember!</h1> </div>
  65. 65. Ember-Data •A Data Persistence Library for Ember.js
  66. 66. Ember-Data •A Data Persistence Library for Ember.js •We’ve created a Mura ORM Adapter for Ember-Data
  67. 67. Ember-Data •A Data Persistence Library for Ember.js •We’ve created a Mura ORM Adapter for Ember-Data •Sooo…
  68. 68. Ember-Data component extends="mura.bean.beanORM" 
 entityName="widget" table="widgets" { property name="widgetid" fieldtype=“id"; property name="name" type=“string"

length="100" required=true message="The name attribute is required an must be.";
 property name="options" singularname="option" fieldtype="one-to-many" cfc="option" cascade="delete"; }
  69. 69. Ember-Data App.Widget = DS.Model.extend({ primaryKey: 'widgetid', widgetid: DS.attr(), siteid: DS.attr(), name: DS.attr(), options: DS.hasMany('Option',{async:true}) });
  70. 70. Ember-Data component extends="mura.bean.beanORM" entityName="option" table="widgetoptions" { property name="optionid" fieldtype="id"; property name="name" type="string" length="100" required=true message="The name attribute is required an must be."; property name="widget" fieldtype="many-to-one" cfc="widget" fkcolumn="widgetid"; }
  71. 71. Ember-Data App.Option = DS.Model.extend({ primaryKey: 'optionid', optionid: DS.attr(), siteid: DS.attr(), name: DS.attr(), widgetid: DS.attr(), widget: DS.belongsTo('Widget',{async:true}) });
  72. 72. Ember-Data App.WidgetRoute = Ember.Route.extend({ model: function(params) { return this.store.find(‘Widget’,params.widgetid); } });
  73. 73. Ember-Data <script type="text/x-handlebars" id=“widget"> <h3>{{name}} ({{options.length}})</h3> {{#if options.length}} <ul> {{#each option in options}} <li>{{option.name}}</li> {{/each}} </ul> {{/if}} </script>
  74. 74. Ember.js •We’re currently prototyping an Ember.js based front for Mura
  75. 75. Ember.js •We’re currently prototyping an Ember.js based front for Mura •It will allow Mura to run as a service
  76. 76. Ember.js •We’re currently prototyping an Ember.js based front for Mura •It will allow Mura to run as a service •This will allow Mura sites to be served locally on any web server without needing a servlet container.
  77. 77. Ember.js •We’re currently prototyping an Ember.js based front for Mura •It will allow Mura to run as a service •This will allow Mura sites to be served locally on any web server without needing a servlet container. •We feel at this point it’s a perfect fit

×