-
Notifications
You must be signed in to change notification settings - Fork 35
Greenfield Quick Start
This is designed to be a super-streamlined process to get you working with CDQ in a brand new application. It leaves a lot out, but it's the fastest way to kick the tires.
$ gem install cdq
$ motion create cdqsample
$ cd cdqsample
$ cdq init
$ bundle install
Now go edit schemas/0001_initial.rb. There's some commented-out example code in it. Go ahead and uncomment the example entities and save the file. It should look like this:
schema "0001 initial" do
# Examples:
#
entity "Person" do
string :name, optional: false
has_many :posts
end
entity "Post" do
string :title, optional: false
string :body
datetime :created_at
datetime :updated_at
has_many :replies, inverse: "Post.parent"
belongs_to :parent, inverse: "Post.replies"
belongs_to :person
end
end
Now to generate models for the entities, Person and Post, that you've just set up in the schema. CDQ includes a handy generator to save a little time:
$ cdq create model person
$ cdq create model post
You're now ready to run rake and start playing with your data. The simulator should come up cleanly.
Once you have a console prompt, start creating some data:
marie = Person.create(name: "Marie Skłodowska")
pierre = Person.create(name: "Pierre Curie")
post = marie.posts.create(title: "First Post", body: "This stuff seems to be glowing.", created_at: Time.now)
post.replies.create(title: "Marry Me!", body: "That is so freaking amazing!", person: pierre, created_at: Time.now)
cdq.save
Note that unlike ActiveRecord, created_at will not (currently) get set automatically.
Now quit the app and restart so you can verify that things are saving to disk correctly.
When you're looking around, you may notice something strange. Sometimes when you run a query, especially for the first time, you get a result like this:
(main)> Person.all.array
=> [<Person: 0x9288d30> (entity: Person; id: 0x9285150 <x-coredata://FD49F7ED-9459-4675-A00F-4CF8B6C1419E/Person/p1> ; data: <fault>), <Person: 0x9288f80> (entity: Person; id: 0x9285160 <x-coredata://FD49F7ED-9459-4675-A00F-4CF8B6C1419E/Person/p2> ; data: <fault>)]
Very compact. But other times, it might look like this:
(main)> Person.all.map(&:name)
=> ["Marie Skłodowska", "Pierre Curie"]
(main)> Person.all.array
=> [<Person: 0x9288d30> (entity: Person; id: 0x9285150 <x-coredata://FD49F7ED-9459-4675-A00F-4CF8B6C1419E/Person/p1> ; data: {
name = "Marie Sk\U0142odowska";
posts = "<relationship fault: 0x9280260 'posts'>";
}), <Person: 0x9288f80> (entity: Person; id: 0x9285160 <x-coredata://FD49F7ED-9459-4675-A00F-4CF8B6C1419E/Person/p2> ; data: {
name = "Pierre Curie";
posts = "<relationship fault: 0x9290540 'posts'>";
})]
Not so compact, but more useful. What's going on? Core Data is very smart
about how much data to load, and won't go fetch the details of an object until
they're used. So in the first example, I'd just loaded the app and hadn't used
anything yet, so you see the text data: <fault>
in there indicating that
it hasn't fetched the attributes from the SQLite database that actually holds
all your data. In the second example, I deliberately loop through each object
and ask it for data, so now when I print out the collection, it shouls you all the
attributes. But you'll note that for posts, it still says "relationship fault",
because we haven't asked it about posts yet. Turtles all the way down.
Now try some queries:
pierre = Person.where(:name).contains("Pierre").first
marie = Person.where(:name).ne("Pierre Curie").first
Post.where(:person).eq(pierre).array
Post.sort_by(:title).first
Post.sort_by(:created_at)[1]
Post.count
Create some more data and then run the queries again, or try some new combinations.