Iuri Matias edited this page Dec 9, 2013 · 6 revisions

Where's MotionModel Going and Why?

There have been a number of changes to MotionModel since the last time I made a widespread announcement, so I thought I'd take the time to discuss them and where I expect to go from here.

First: I'd like to put out a call for active contribution and specs for problems you encounter. Fixing problems makes it possible for us to move quickly. Creating the test case at least allows us to reproduce the problem. okthxbye.


This is great. It means there are real people using MotionModel (kidding). There have been a number of issues since we changed to adapters. Before I get into those, let me explain why we felt adapters were necessary.

Why Adapters?

The original goal of MotionModel was to be a simple little DSL that let you use your ActiveRecord muscle-memory to store and manipulate business objects. Your data. It seems the relational model is a pretty good one and it sticks with people and that can be a barrier to enthusiastic adoption of Core Data. So… MotionModel bypassed Core Data and simply used NSCoding to serialize. The data is simply stored in files.

But then @aceofspades came up with the idea of integrating MotionModel and SQLite (and, incidentally, it seems SQLite is the preferred backing store behind Core Data anyhow). Through Doug's wonderful refactoring, we have been able to create two different branches of the project, each one for a different adapter.

The ArrayModelAdapter is the original one that uses NSCoding, and the FMDBModelAdapter. FMDBModelAdapter is, in my opinion, a pretty heroic effort -- it uses the FMDB Cocoapod to connect to the SQLite database engine, and all the ActiveRecord-like finders and associations are magically turned into SQL. It's almost like … um … Rails.

So, Again, the Issues

As more people are starting to investigate MotionModel and understand its issues when applied to their own problem set, issues are raised. Kudos to everyone who raised issues, and especially to those who provided examples or (even better) failing specs or (way better) a failing spec and a fix.

We've learned a lot about RubyMotion and how it interacts with iOS along the way (at least I have), and discovered that iOS's magical dynamic subclassing of Ruby classes for KVO bypasses all the normal Ruby hooks that allow us to know this is happening (!!!).


It has become clear to me that while MotionModel's ArrayModelAdapter is great for organizing code for the small data case, it can lead to performance issues when your data grows. Here's why:

  • MotionModel's ArrayModelAdapter was never meant to do heavy lifting. It was meant to enable an ActiveRecord-like pattern around smaller data sets. It is implemented in pure Ruby and makes few assumptions about the "shape" of your data.
  • ArrayModelAdapter doesn't implement indexing nor does it currently recognize any implicit ordering of your data. What that means is that a find.where(:name).eq('jones') will do a Ruby select. This is an O(n) operation and its expected cost increases proportionate to the number of items in your data set. Obviously, for a small data set this is a very small price to pay for the simplicity of ArrayModelAdapter. However, planning for future expansion of data, you will see that you cannot take advantage of database features you have come to expect such as indexing and execution plans.

By contrast to the ArrayModelAdapter, the FMDBModelAdapter sits atop FMDB, which sits atop SQLite.


  • Keep the syntax as close to that of ArrayModelAdapter as possible.
  • Make it possible to optimize for larger data cases.
  • Take advantage of a backing store that is battle tested and present on iOS and OSX by default.

Where We Plan To Go

The current plan is to continue to address issues in the ArrayModelAdapter but not to add functionality -- at least the core team. We feel that by focusing on the FMDBModelAdapter, we can provide a better long-term solution with little syntactic-vinegar for users.

How to Jump On Board

The ArrayModelAdapter currently is in master and is also what is packaged into gems. The FMDBModelAdapter is in the sql branch and we have not yet begun packaging it into gems. Here's how to get at either one:

# Gemfile
# ...
gem 'motion_model', git:'', branch:'master'  # ArrayModelAdapter
# -or-
gem 'motion_model', git:'', branch:'sql'  # FMDBModelAdapter

Now, if you do decide to take the FMDBModelAdapter out for a spin, you will have to add a bit to your Rakefile:

# -*- coding: utf-8 -*-
require "bundler/gem_tasks"
require 'motion/project/template/ios'
require 'bundler'

require 'motion-cocoapods'

require 'motion_model'
require 'motion_model/array'
require 'motion_model/sql'
require 'motion_model/fmdb'

Motion::Project::App.setup do |app|
  # Use `rake config' to see complete project settings. = 'Your App Name'
  app.delegate_class = 'AppDelegate'

All other documentation pretty much applies.

How to Submit Issues

This has changed a bit. We need to know which branch you are finding issues with. If you have an issue, please name the branch in your issue or pull request. More importantly, if you are submitting a pull request, make sure it's a request to the proper branch.

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.