Skip to content

Greenfield Quick Start

kemiller edited this page Jan 4, 2014 · 2 revisions

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.

Installation

$ gem install cdq
$ motion create cdqsample
$ cd cdqsample
$ cdq init
$ bundle install

Schema

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

Models

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

Creating Data

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.

An aside about data faults

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.

Queries

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.