Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 144 lines (105 sloc) 5.589 kB
e8b4f3b @sam Importing from old repository.
sam authored
1
2 :include:QUICKLINKS
3
4 = Why DataMapper?
5
6 == Open Development
7
0ba594d @myabc Fixed Ruby 1.9 compatibility (use of : shorthand for 'then') in DataM…
myabc authored
8 DataMapper sports a very accessible code-base and a welcoming community.
e8b4f3b @sam Importing from old repository.
sam authored
9 Outside contributions and feedback are welcome and encouraged, especially
10 constructive criticism. Make your voice heard! Submit a
11 ticket[http://wm.lighthouseapp.com/projects/4819-datamapper/overview] or
12 patch[http://wm.lighthouseapp.com/projects/4819-datamapper/overview], speak up
13 on our mailing-list[http://groups.google.com/group/datamapper/], chat with us
14 on irc[irc://irc.freenode.net/#datamapper], write a spec, get it reviewed, ask
15 for commit rights. It's as easy as that to become a contributor.
16
17 == Identity Map
18
6341058 rewriting docs for dm-point-nine
Adam French authored
19 One row in the data-store should equal one object reference. Pretty simple idea.
e8b4f3b @sam Importing from old repository.
sam authored
20 Pretty profound impact. If you run the following code in ActiveRecord you'll
21 see all <tt>false</tt> results. Do the same in DataMapper and it's
22 <tt>true</tt> all the way down.
23
24 @parent = Tree.find(:first, :conditions => ['name = ?', 'bob'])
25
26 @parent.children.each do |child|
27 puts @parent.object_id == child.parent.object_id
28 end
29
30 This makes DataMapper faster and allocate less resources to get things done.
31
f85303d readme changes, and quieting yardocs warnings...will need to go back …
Adam French authored
32 == Dirty Tracking
e8b4f3b @sam Importing from old repository.
sam authored
33
f85303d readme changes, and quieting yardocs warnings...will need to go back …
Adam French authored
34 When you save a model back to your data-store, DataMapper will only write
35 the fields that actually changed. So it plays well with others. You can
6341058 rewriting docs for dm-point-nine
Adam French authored
36 use it in an Integration data-store without worrying that your application will
e8b4f3b @sam Importing from old repository.
sam authored
37 be a bad actor causing trouble for all of your other processes.
38
f85303d readme changes, and quieting yardocs warnings...will need to go back …
Adam French authored
39 You can also configure which strategy you'd like to use to track dirtiness.
40
e8b4f3b @sam Importing from old repository.
sam authored
41 == Eager Loading
42
43 Ready for something amazing? The following example executes only two queries.
44
98eb950 Minor formatting cleanup on README
Dan Kubb authored
45 zoos = Zoo.all
46 first = zoos.first
e571600 Updated Relationship#initialize to use positional arguments
Dan Kubb authored
47 first.exhibits # Loads the exhibits for all the Zoo objects in the zoos variable.
e8b4f3b @sam Importing from old repository.
sam authored
48
49 Pretty impressive huh? The idea is that you aren't going to load a set of
50 objects and use only an association in just one of them. This should hold up
51 pretty well against a 99% rule. When you don't want it to work like this, just
52 load the item you want in it's own set. So the DataMapper thinks ahead. We
53 like to call it "performant by default". This feature single-handedly wipes
54 out the "N+1 Query Problem". No need to specify an <tt>include</tt> option in
55 your finders.
56
57 == Laziness Can Be A Virtue
58
6341058 rewriting docs for dm-point-nine
Adam French authored
59 Text fields are expensive in data-stores. They're generally stored in a
e8b4f3b @sam Importing from old repository.
sam authored
60 different place than the rest of your data. So instead of a fast sequential
6341058 rewriting docs for dm-point-nine
Adam French authored
61 read from your hard-drive, your data-store server has to hop around all over the
e8b4f3b @sam Importing from old repository.
sam authored
62 place to get what it needs. Since ActiveRecord returns everything by default,
6341058 rewriting docs for dm-point-nine
Adam French authored
63 adding a text field to a table slows everything down drastically, across the
e8b4f3b @sam Importing from old repository.
sam authored
64 board.
65
66 Not so with the DataMapper. Text fields are treated like in-row associations
67 by default, meaning they only load when you need them. If you want more
6341058 rewriting docs for dm-point-nine
Adam French authored
68 control you can enable or disable this feature for any field (not just
69 text-fields) by passing a @lazy@ option to your field mapping with a value of
e8b4f3b @sam Importing from old repository.
sam authored
70 <tt>true</tt> or <tt>false</tt>.
71
0ba594d @myabc Fixed Ruby 1.9 compatibility (use of : shorthand for 'then') in DataM…
myabc authored
72 class Animal
73 include DataMapper::Resource
74 property :name, String
6341058 rewriting docs for dm-point-nine
Adam French authored
75 property :notes, Text, :lazy => false
e8b4f3b @sam Importing from old repository.
sam authored
76 end
77
78 Plus, lazy-loading of text fields happens automatically and intelligently when
79 working with associations. The following only issues 2 queries to load up all
80 of the notes fields on each animal:
81
98eb950 Minor formatting cleanup on README
Dan Kubb authored
82 animals = Animal.all
83 animals.each do |pet|
e8b4f3b @sam Importing from old repository.
sam authored
84 pet.notes
85 end
86
87 == Plays Well With Others
88
6341058 rewriting docs for dm-point-nine
Adam French authored
89 In ActiveRecord, all your fields are mapped, whether you want them or not.
e8b4f3b @sam Importing from old repository.
sam authored
90 This slows things down. In the DataMapper you define your mappings in your
6341058 rewriting docs for dm-point-nine
Adam French authored
91 model. So instead of an _ALTER TABLE ADD field_ in your data-store, you simply
e8b4f3b @sam Importing from old repository.
sam authored
92 add a <tt>property :name, :string</tt> to your model. DRY. No schema.rb. No
93 migration files to conflict or die without reverting changes. Your model
6341058 rewriting docs for dm-point-nine
Adam French authored
94 drives the data-store, not the other way around.
e8b4f3b @sam Importing from old repository.
sam authored
95
6341058 rewriting docs for dm-point-nine
Adam French authored
96 Unless of course you want to map to a legacy data-store. Raise your hand if you
e8b4f3b @sam Importing from old repository.
sam authored
97 like seeing a method called <tt>col2Name</tt> on your model just because
6341058 rewriting docs for dm-point-nine
Adam French authored
98 that's what it's called in an old data-store you can't afford to change right
e8b4f3b @sam Importing from old repository.
sam authored
99 now? In DataMapper you control the mappings:
100
0ba594d @myabc Fixed Ruby 1.9 compatibility (use of : shorthand for 'then') in DataM…
myabc authored
101 class Fruit
102 include DataMapper::Resource
99388e4 @atmos set_table_name is now storage_names, update README
atmos authored
103 storage_names[:repo] = 'frt'
6341058 rewriting docs for dm-point-nine
Adam French authored
104 property :name, String, :field => 'col2Name'
e8b4f3b @sam Importing from old repository.
sam authored
105 end
106
107 == All Ruby, All The Time
108
109 It's great that ActiveRecord allows you to write SQL when you need to, but
110 should we have to so often?
111
6341058 rewriting docs for dm-point-nine
Adam French authored
112 DataMapper supports issuing your own query, but it also provides more helpers
e8b4f3b @sam Importing from old repository.
sam authored
113 and a unique hash-based condition syntax to cover more of the use-cases where
114 issuing your own SQL would have been the only way to go. For example, any
115 finder option that's non-standard is considered a condition. So you can write
116 <tt>Zoo.all(:name => 'Dallas')</tt> and DataMapper will look for zoos with the
117 name of 'Dallas'.
118
119 It's just a little thing, but it's so much nicer than writing
120 <tt>Zoo.find(:all, :conditions => ['name = ?', 'Dallas'])</tt>. What if you
121 need other comparisons though? Try these:
122
123 Zoo.first(:name => 'Galveston')
124
e571600 Updated Relationship#initialize to use positional arguments
Dan Kubb authored
125 # 'gt' means greater-than. We also do 'lt'.
126 Person.all(:age.gt => 30)
e8b4f3b @sam Importing from old repository.
sam authored
127
128 # 'gte' means greather-than-or-equal-to. We also do 'lte'.
129 Person.all(:age.gte => 30)
130
131 Person.all(:name.not => 'bob')
132
133 # If the value of a pair is an Array, we do an IN-clause for you.
134 Person.all(:name.like => 'S%', :id => [1, 2, 3, 4, 5])
135
e571600 Updated Relationship#initialize to use positional arguments
Dan Kubb authored
136 # An alias for Zoo.find(11)
137 Zoo[11]
e8b4f3b @sam Importing from old repository.
sam authored
138
d70e882 Another small formatting cleanup of README
Dan Kubb authored
139 # Does a NOT IN () clause for you.
140 Person.all(:name.not => ['bob','rick','steve'])
e8b4f3b @sam Importing from old repository.
sam authored
141
142 See? Fewer SQL fragments dirtying your Ruby code. And that's just a few of the
143 nice syntax tweaks DataMapper delivers out of the box...
Something went wrong with that request. Please try again.