Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
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.
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.
ArrayModelAdapter is the original one that uses
NSCoding, and the
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:
ArrayModelAdapterwas 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.
ArrayModelAdapterdoesn'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.
- Keep the syntax as close to that of
- 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
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:'https://github.com/sxross/MotionModel.git', branch:'master' # ArrayModelAdapter # # -or- # gem 'motion_model', git:'https://github.com/sxross/MotionModel.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" $:.unshift("/Library/RubyMotion/lib") require 'motion/project/template/ios' require 'bundler' Bundler.require(:default) 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. app.name = 'Your App Name' app.delegate_class = 'AppDelegate' end
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.