motion-realm
gem has been made to Rubyfy Realm's syntax. You will
still need to read some Realm's docs in order to understand how it works. Also because
of Realm's specific, we still have to vendor Objective-C schema files.
It's recommanded to integrate with CocoaPods
:
Add this line to your application's Gemfile, then run bundle install
:
gem 'motion-cocoapods'
Add this line to your application's Rakefile, then run rake pod:install
:
app.pods do
pod 'Realm'
end
Tell rubymotion to include schemas. In your Rakefile
add:
app.vendor_project 'schemas', :static, cflags: '-I"../vendor/Pods/Headers/Public"'
You can also install by compiling Realm from their sources available at https://github.com/realm/realm-cocoa
git clone https://github.com/realm/realm-cocoa
cd realm-cocoa
sh build.sh build
When build will be finished, copy build/ios/Realm.framework
into your app's vendor/realm
folder. Don't forget to create schemas
folder that will contain your DB schema definitions.
Now we need to tell Rubymotion to include realm and schemas. In your Rakefile
add:
app.libs << '/usr/lib/libc++.dylib'
app.external_frameworks << 'vendor/realm/Realm.framework'
app.vendor_project 'schemas', :static, :cflags => '-F ../vendor/realm/'
You can start using Realm in your project now.
Add this line to your application's Gemfile:
gem 'motion-realm'
And then execute:
$ bundle
Or install it yourself as:
$ gem install motion-realm
Your schemas should be defined in /schemas
folder. Unfortunately because of
the Realm's specific we will have to use Objective-C here. You can check Realm's docs on models at https://realm.io/docs/objc/latest/#models
schemas/schema.h
#import <Realm/Realm.h>
@class Parent;
@interface Child : RLMObject
@property BOOL likes_math;
@property NSInteger favourite_number;
@property NSString *name;
@property NSString *sex;
@property NSDate *birthday;
@property NSData *some_data;
@property Parent *parent;
@end
RLM_ARRAY_TYPE(Child)
@interface Parent : RLMObject
@property NSString *job;
@property NSString *name;
@property NSString *sex;
@property NSDate *birthday;
@property BOOL likes_ruby;
@property NSInteger apps_in_appstore;
@property NSData *some_data;
@property RLMArray<Child *> <Child> *children;
@end
And don't forget about implementation .m
file:
schemas/schema.m
#import "schema.h"
@implementation Child
@end
@implementation Parent
@end
Now when we have schema defined, we can create app/models/child.rb
and
app/models/parent.rb
:
class Child
# it is important to include MotionRealm module in your model classes:
include MotionRealm
# if you want to set some default values, do it in this method:
def self.default_values
{
likes_math: true,
}
end
# indexes can be defined here:
def self.indexes
["name", "favourite_number"]
end
# primary key, if needed:
def self.primary_key
"name"
end
end
class Parent
include MotionRealm
end
This is it! Schema and Models were defined, and everything is ready for usage!
# create in-memory objects:`
child = Child.new
child.name = "John"
parent = Parent.create name: "Jack"
parent.children << child
# persist them:
RLMRealm.write do |realm|
realm << child
realm << parent
end
# find objects:
parent = Parent.where("name = 'Jack'").first
# or using predicates:
predicate = NSPredicate.predicateWithFormat "name == %@", "some cool name"
cool_parents = Parent.with_predicate predicate
# we have to update objects inside write block only:
RLMRealm.write do |realm|
parent.name = 'Jack Smith'
end
# delete objects:
parent.delete
# or
RLMRealm.write do |realm|
realm.delete parent
end
# delete all objects:
RLMRealm.write do |realm|
realm.delete_all
end
# or all objects for a given class:
Parent.delete_all
result = RLMRealm.write do |realm|
# add objects to realm, update objects, delete them here
end
# result is a Hash: { saved: true/false, error: error_if_any }
# RLMRealm.write is just a shorthand for:
realm = RLMRealm.default
realm.start_writing
# add objects to realm, update objects, delete them here
realm.end_writing
By default if you are going to save an object without setting all its properties to some value, they will be set to:
- Number or Mixed property to 0
- Array properties to []
- All other properties will be set to Nil.
If you want to change this behaviour, you can use class method default_values
.
For example:
def self.default_values
{
bool_prop: true,
int_prop: 1
}
end
You can post notifications each time realm data has been updated. To do it just tell your realm that you want to add a notification:
@notification_token = realm.add_notification do |notification, realm|
# some your actions here
end
Don't forget to remove it when you won't need it anymore with:
realm.remove_notification @notification_token
Sometimes we have to update DB schema. Realm's docs describe it very well at https://realm.io/docs/objc/latest/#migrations
To migrate your DB to a newer schema version, you can use RLMRealmConfiguration.migrate_to_version(new_version, &block)
method.
It is a good idea to use non-nested if
conditions, because some users
may update your app rarely, and they may accidentally skip migration from X to Y
schema version:
RLMRealmConfiguration.migrate_to_version(3) do |migration, old_version|
migration.enumerate "Parent" do |old_object, new_object|
# user has not updated his app to the 1st schema version yet:
if old_version < 1
# migrate the object to 1st version
end
# user had 1st version of the schema already:
if old_version < 2
# migrate the object to the 2nd version
end
# user had latest available schema. Update him to a newer one:
if old_version < 3
# migrate the object to the 3rd version
end
end
end
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request