public
Rubygem
Description: DataMapper - Core
Homepage: http://datamapper.org
Clone URL: git://github.com/sam/dm-core.git
Search Repo:
rewriting docs for dm-point-nine
Adam French (author)
Thu May 08 09:07:38 -0700 2008
commit  63410587d913b3a749316d07f9d3fde1234d32fb
tree    ad60abdc5a287d16abfdb8ff2c25d21285f5bec5
parent  d18d2d5d4a8feba60d4e59a1c9683542831ae1bb
0
FAQ
...
2
3
4
5
6
 
7
8
9
10
 
 
11
12
 
13
14
15
16
 
17
 
18
19
 
 
20
21
 
 
22
23
24
25
26
 
27
28
 
29
30
 
 
31
32
 
 
 
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
 
50
51
52
 
53
54
55
56
57
58
59
60
 
 
 
61
62
63
64
65
66
67
68
69
70
71
 
 
72
73
74
75
76
77
78
 
79
80
 
81
82
83
84
85
86
87
 
88
89
90
91
92
 
93
94
95
96
97
 
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
 
 
 
 
 
...
2
3
4
 
 
5
6
 
 
 
7
8
9
 
10
11
 
 
 
12
13
14
15
 
16
17
18
 
19
20
21
 
 
 
 
22
23
 
24
25
 
26
27
28
 
29
30
31
32
 
 
 
 
 
 
 
 
 
 
 
 
 
33
34
 
35
36
37
38
39
40
41
42
43
44
 
 
 
45
46
47
48
 
 
 
 
 
49
50
 
 
 
51
52
53
 
 
54
55
56
 
57
58
 
59
60
 
61
 
 
 
 
62
63
 
 
 
 
64
65
 
 
 
 
66
67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
69
 
70
71
72
73
74
0
@@ -2,125 +2,74 @@
0
 
0
 = FAQ
0
 
0
-=== I don't want to use :id as a primary key, but I don't see
0
-=== <tt>set_primary_key</tt> anywhere. What do I do?
0
+=== So where's my :id column?
0
 
0
-If you're working with a table that doesn't have a <tt>:id</tt> column, you
0
-can declare your properties as you usually do, and declare one of them as a
0
-natural key.
0
+DataMapper will NOT create an auto-incrementing <tt>:id</tt> key for you
0
+automatically, so you'll need to either explicitly create one with
0
 
0
- property :name, String, :key => true
0
+ property :id, Fixnum, :serial => true
0
 
0
-You should now be able to do <tt>Class['name_string']</tt> as well. Remember:
0
-this column should be unique, so treat it that way. This is the equivalent to
0
-using <tt>set_primary_key</tt> in ActiveRecord.
0
+You can choose to use a natural key by doing
0
 
0
+ property :slug, String, :key => true
0
 
0
-=== How do I make a model paranoid?
0
+Remember, DataMapper supports multiple keys ("composite keys"), so if your
0
+model has two or more keys, no big deal
0
 
0
- property :deleted_at, DateTime
0
+ property :store_id, Fixnum, :key => true
0
+ property :invoice_id, Fixnum, :key => true
0
 
0
-If you've got deleted_at, your model is paranoid auto-magically. All of your
0
-calls to <tt>##all()</tt>, <tt>##first()</tt>, and <tt>##count()</tt> will be
0
-scoped with <tt>where deleted_at is null</tt>. Plus, you won't see deleted
0
-objects in your associations.
0
+=== How do I make a model paranoid?
0
 
0
-=== Does DataMapper support Has Many Through?
0
+Create a property and make it a ParanoidDateTime or ParanoidBoolean type.
0
 
0
-Write me!
0
+ property :deleted_at, ParanoidDateTime
0
+ property :deleted, ParanoidBoolean
0
 
0
-=== What about Self-Referential Has And Belongs to Many?
0
+All of your calls to <tt>##all()</tt>, <tt>##first()</tt> will be scoped
0
+with <tt>:deleted_at => nil</tt> or <tt>:deleted => false</tt>. Plus,
0
+you won't see deleted objects in your associations.
0
 
0
-Sure does. Here's an example implementation:
0
-
0
- class Task
0
- include DataMapper::Resource
0
- many_to_many :tasks,
0
- :join_table => "task_relationships", :left_foreign_key => "parent_id",
0
- :right_foreign_key => "child_id"
0
- end
0
-
0
-You'll notice that instead of <tt>foreign_key</tt> and
0
-<tt>association_foreign_key</tt>, DataMapper uses the "database-y" terms
0
-<tt>left_foreign_key</tt>, and <tt>right_foreign_key</tt>.
0
-
0
 === Does DataMapper do Single Table Inheritance?
0
 
0
-Oh yes, and particularly well too.
0
+This is what the Class data-type is for:
0
 
0
   class Person
0
     include DataMapper::Resource
0
+ property :id, Fixnum, :serial => true
0
     property :type, Class ## other shared properties here
0
   end
0
 
0
   class Salesperson < Person; end
0
 
0
-You can claim a column to have the type <tt>:class</tt> and DataMapper will
0
-automatically drop the class name of the inherited classes into that column of
0
-the database.
0
+You can claim a column to have the type <tt>Class</tt> and DataMapper will
0
+automatically drop the class name of the inherited classes into that field of
0
+the data-store.
0
 
0
-=== What about Class Table Inheritance?
0
-
0
-Class Table Inheritance is on the drawing board and everyone's drooling over
0
-it. So no, not yet, but soon.
0
-
0
 === How do I run my own commands?
0
 
0
-You're probably asking for <tt>find_by_sql</tt>, and DataMapper has that in
0
-it's ActiveRecordImpersonation, but if you want to go straight-up DataMapper,
0
-you'll want to use <tt>repository.query</tt>
0
+ repository.adapter.query("select * from users where clue > 0")
0
+ repository(:integration).adapter.query("select * from users where clue > 0")
0
 
0
- repository.query("select * from users where clue > 0")
0
-
0
 This does not return any Users (har har), but rather Struct's that will quack
0
 like Users. They'll be read-only as well.
0
 
0
-<tt>repository..query</tt> shouldn't be used if you aren't expecting a result set
0
+<tt>repository.adapter.query</tt> shouldn't be used if you aren't expecting a result set
0
 back. If you want to just execute something against the database, use
0
-<tt>repository..execute</tt> instead.
0
+<tt>repository.adapter.execute</tt> instead.
0
 
0
-=== Can I batch-process a ton of records at once?
0
 
0
- User.each(:performance_rating => "low") do |u|
0
- u.employment_status = "fired"
0
- u.save
0
- end
0
+=== Can I get an query log of what DataMapper is issuing?
0
 
0
-With ActiveRecord, doing a <tt>User.find(:all).each{}</tt> would execute the
0
-find, instantiate an object for EVERY result, THEN apply your transformations
0
-to each object in turn. Doesn't sound too horrible unless you have a TON of
0
-records; you WILL grind your system to a screeching and bloody halt.
0
+Yup, to set this up, do:
0
 
0
-DataMapper's <tt>#each</tt> works in sets of 500 so the amount of objects
0
-instantiated at a time won't make your computer think it's a victim in a Saw
0
-movie. Once it's done executing your block on the first set of 500, it moves
0
-on to the next.
0
+ DataMapper.logger = Logger.new("/path/to/your/logger.log", "w+")
0
 
0
-What's more is <tt>#each</tt> is secretly a finder too. You can pass it an
0
-options hash and it'll only iterate on 500-item sets matching your query.
0
-Don't send it <tt>:offset</tt> though, because that's how it pages. You can
0
-overload the page size by sending it <tt>:limit</tt>
0
-
0
-=== Can I get an SQL log of what queries DataMapper is issuing?
0
-
0
-Yup, when you issue <tt>Repository.setup</tt>, tack on the <tt>log_stream</tt>
0
-and <tt>log_level</tt>:
0
-
0
- DataMapper::Repository.setup({
0
- :adapter => 'mysql', :host => 'localhost', :username => 'root',
0
- :password => 'R00tPaswooooord', :database =>
0
- 'myspiffyblog_development', :log_stream => 'log/sql.log', :log_level => 0
0
- })
0
-
0
-By supplying the <tt>log_stream</tt> you're telling DataMapper what file you
0
-want to see your sql logs in. <tt>log_level</tt> is the
0
-Logger[http://www.ruby-doc.org/stdlib/libdoc/logger/rdoc/] level of output you
0
-want to see there. 0, in this case, says that you want to see all DEBUG level
0
-messages (and higher) sent to the logger. For more information on how to work
0
-with Logger[http://www.ruby-doc.org/stdlib/libdoc/logger/rdoc/], hit up
0
-http://www.ruby-doc.org/stdlib/libdoc/logger/rdoc/.
0
-
0
 Incidentally, if you'd like to send a message into the DataMapper logger, do:
0
 
0
- repository.adapter.logger.info "your message here"
0
+ DataMapper.logger.debug { "something" }
0
+ DataMapper.logger.info { "something" }
0
+ DataMapper.logger.warn { "something" }
0
+ DataMapper.logger.error { "something" }
0
+ DataMapper.logger.fatal { "something" }
0
...
16
17
18
19
 
20
21
22
23
...
31
32
33
34
 
35
36
37
38
39
40
 
41
42
43
44
45
46
47
...
58
59
60
61
 
62
63
 
64
65
 
66
67
68
69
70
71
 
 
72
73
74
75
76
77
 
78
79
80
81
82
83
84
85
...
88
89
90
91
 
92
93
 
94
95
96
 
97
98
 
99
100
 
101
102
103
104
105
106
 
107
108
109
...
111
112
113
114
 
115
116
117
...
143
144
145
146
147
148
149
150
151
152
...
16
17
18
 
19
20
21
22
23
...
31
32
33
 
34
35
36
37
38
39
 
40
41
42
43
44
45
46
47
...
58
59
60
 
61
62
 
63
64
 
65
66
67
68
69
 
 
70
71
72
73
74
75
76
 
77
78
79
80
81
82
83
84
85
...
88
89
90
 
91
92
 
93
94
95
 
96
97
 
98
99
 
100
101
102
103
104
105
 
106
107
108
109
...
111
112
113
 
114
115
116
117
...
143
144
145
 
 
 
 
 
 
 
0
@@ -16,7 +16,7 @@
0
 
0
 == Identity Map
0
 
0
-One row in the database should equal one object reference. Pretty simple idea.
0
+One row in the data-store should equal one object reference. Pretty simple idea.
0
 Pretty profound impact. If you run the following code in ActiveRecord you'll
0
 see all <tt>false</tt> results. Do the same in DataMapper and it's
0
 <tt>true</tt> all the way down.
0
0
@@ -31,13 +31,13 @@
0
 
0
 == Don't Do What You Don't Have To
0
 
0
-ActiveRecord updates every column in a row during a save whether that column
0
+ActiveRecord updates every field in a row during a save whether that field
0
 changed or not. So it performs work it doesn't really need to making it much
0
 slower, and more likely to eat data during concurrent access if you don't go
0
 around adding locking support to everything.
0
 
0
 DataMapper only does what it needs to. So it plays well with others. You can
0
-use it in an Integration Database without worrying that your application will
0
+use it in an Integration data-store without worrying that your application will
0
 be a bad actor causing trouble for all of your other processes.
0
 
0
 == Eager Loading
0
0
0
0
0
@@ -58,23 +58,23 @@
0
 
0
 == Laziness Can Be A Virtue
0
 
0
-Text columns are expensive in databases. They're generally stored in a
0
+Text fields are expensive in data-stores. They're generally stored in a
0
 different place than the rest of your data. So instead of a fast sequential
0
-read from your hard-drive, your database server has to hop around all over the
0
+read from your hard-drive, your data-store server has to hop around all over the
0
 place to get what it needs. Since ActiveRecord returns everything by default,
0
-adding a text column to a table slows everything down drastically, across the
0
+adding a text field to a table slows everything down drastically, across the
0
 board.
0
 
0
 Not so with the DataMapper. Text fields are treated like in-row associations
0
 by default, meaning they only load when you need them. If you want more
0
-control you can enable or disable this feature for any column (not just
0
-text-fields) by passing a @lazy@ option to your column mapping with a value of
0
+control you can enable or disable this feature for any field (not just
0
+text-fields) by passing a @lazy@ option to your field mapping with a value of
0
 <tt>true</tt> or <tt>false</tt>.
0
 
0
   class Animal
0
     include DataMapper::Resource
0
     property :name, String
0
- property :notes, DataMapper::Types::Text, :lazy => false
0
+ property :notes, Text, :lazy => false
0
   end
0
 
0
 Plus, lazy-loading of text fields happens automatically and intelligently when
0
0
0
0
0
0
@@ -88,22 +88,22 @@
0
 
0
 == Plays Well With Others
0
 
0
-In ActiveRecord, all your columns are mapped, whether you want them or not.
0
+In ActiveRecord, all your fields are mapped, whether you want them or not.
0
 This slows things down. In the DataMapper you define your mappings in your
0
-model. So instead of an _ALTER TABLE ADD COLUMN_ in your Database, you simply
0
+model. So instead of an _ALTER TABLE ADD field_ in your data-store, you simply
0
 add a <tt>property :name, :string</tt> to your model. DRY. No schema.rb. No
0
 migration files to conflict or die without reverting changes. Your model
0
-drives the database, not the other way around.
0
+drives the data-store, not the other way around.
0
 
0
-Unless of course you want to map to a legacy database. Raise your hand if you
0
+Unless of course you want to map to a legacy data-store. Raise your hand if you
0
 like seeing a method called <tt>col2Name</tt> on your model just because
0
-that's what it's called in an old database you can't afford to change right
0
+that's what it's called in an old data-store you can't afford to change right
0
 now? In DataMapper you control the mappings:
0
 
0
   class Fruit
0
     include DataMapper::Resource
0
     storage_names[:repo] = 'frt'
0
- property :name, String, :column => 'col2Name'
0
+ property :name, String, :field => 'col2Name'
0
   end
0
 
0
 == All Ruby, All The Time
0
@@ -111,7 +111,7 @@
0
 It's great that ActiveRecord allows you to write SQL when you need to, but
0
 should we have to so often?
0
 
0
-DataMapper supports issuing your own SQL, but it also provides more helpers
0
+DataMapper supports issuing your own query, but it also provides more helpers
0
 and a unique hash-based condition syntax to cover more of the use-cases where
0
 issuing your own SQL would have been the only way to go. For example, any
0
 finder option that's non-standard is considered a condition. So you can write
0
@@ -143,11 +143,4 @@
0
 
0
 See? Fewer SQL fragments dirtying your Ruby code. And that's just a few of the
0
 nice syntax tweaks DataMapper delivers out of the box...
0
-
0
-== Better Is Great, But Familiar Is Nice
0
-
0
-The DataMapper also supports a lot of old-fashioned ActiveRecord syntax. We
0
-want to make it easy for you to get started, so aside from mapping your
0
-columns and changing the base-class your models inherit from, much of AR
0
-syntax for finders are supported as well, making your transition easy.

Comments

    No one has commented yet.