Volt 0.9.3 Released with Support for Clustering, Simplified Persistence and Improved Validation

Volt versions are rolling out fast as we add the last things we want before 1.0.  We made a quick upgrade guide here, but be sure to read the rest to know about all of the new features.

Moving Questions to StackOverflow

Before we get to the new features in 0.9.3, I wanted to suggest one community change. Previously, we recomended questions about Volt be directed to @ryanstout in Gitter.  While this works great, it also means questions are not easily searchable, so the same questions come up a lot.  Now we are reccomending people post questions on StackOverflow with the tag #voltrb.  The volt team will make sure we respond just as quickly.  Feel free to paste stackoverflow question urls into gitter to get our attention faster.

MultiInstance Cluster & Message Bus

Previously, when you updated a model in the console or a server, it didn’t push the update to other servers/consoles.  Now any model update from a server, console, runner, etc.. will be pushed to all other instances in the “cluster” and to the attached browsers.  A cluster is any volt instance connected to the same database.  We’ll do a larger blog post talking about the default message bus.  Basically though it uses the database to share a list of socket ip’s and ports.  Then an internal encrypted socket network is setup between all instances.  For the end user, as long as each server can see each other, you don’t need to do anything.  Volt uses these connections to push updates internally, but the bus also provides a simple pub/sub interface for app code.

It is also easy to create other message bus’s using different strategies.  For example, we’ll probably add a redis and gnatsd implementation shortly.

Validation Blocks

Volt provides many common validations out of the box (length, presence, unique, etc..)  Often depending on the state of a model, you may need to only run validations at certain times.  In other frameworks, this is done with a :if or :unless option (which takes a proc).  While this works, its not pretty and makes reusing logic difficult.  Volt model’s now have a “validations” method that takes a block.  Inside of the block you can call the “validate” method you would normally call.  The validations block runs during each validation phase with the model as its instance.  This lets you use normal if blocks to control when to run validations.

class Post < Volt::Model
 field :title, String
 field :published, Boolean
 validate :title, length: 5
 validations do
   if published
     validate :publish_date, presence: true
   end
 end
end

See the volt docs for more info.

Data Provider API

We’ve been talking a lot about the data provider api.  The idea is to provide an abstraction for connecting volt’s model layer to any data store.  The data provider api will provide a few simple classes that anyone can implement to tie in querying and updating ability to a data source.  While the data provider API is still in the works, we have all mongo related code pulled into a volt-mongo gem, and we should have full data provider API support in the next release.

Id changes

Volt no longer uses _id as the id for models.  We now use ‘id’ (go figure).  Since mongo uses _id for its id’s, the mongo data provider automatically maps all queries and saves to use _id.

Speaking of id’s, volt now auto-generates id’s for all models on page and store.  This greatly simplifies associations internally since we always have a reference to a model (even before its saved).  Volt has always used GUID’s for id’s, now we just generate them earlier now.

Model Nesting

You can now store another model in a model’s property on store.  Read more here.

Store Access Simplified

Previously when a query was run on the store collection, it may return an empty result set, which would then be updated when the data loads (via reactive loading).  This was confusing for many new users.  To simplify things, we have changed it so data access on the store collection always returns a promise.

We’ve also added some helpers to promise to make promises easier to work with.  First, all bindings now can take promises which will update when the promise resolves.  You can still pass normal values, but Promises will be automatically resolved.  Also, if the promise fails (is rejected), the binding will log an error.

Second, methods called on promises (aside from the build-in methods) will now return a new promise that will call the method when the Promise resolves.  This means you can do something like:

store.posts.first.title

which will return a promise that will return the title from the first post.

Volt.current_user now returns a promise, and Volt.fetch_current_user is now deprecated.  Volt.current_user? also returns a promise.

To make the transition easier to understand, we made an explainer video.

Custom Middleware

You can now add your own Rack middleware.  Components can add middleware also.  This makes it easier to setup something like omniauth.

Read more here

has_one

Finally got around to implementing has_one. It behaves like you would expect, except it returns a promise when used on the store collection.

Improved Model Inspect

We changed around the way models are inspected to make it easier to read.

Calling Contributors

If you’ve been thinking about helping out with Volt, now’s a good time.  Now that many of the core api’s have stabilized, its easier to get into working on volt or component gems.  If you have some time and are interested, hit up @ryanstout on gitter.  

Thanks!

Thanks to all of those who made this release possible and are helping to grow Volt. Its been amazing to watch the excitement around it and the interesting apps people are building.