voraz-dr_nic_magic_models 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/CHANGELOG +9 -0
  2. data/History.txt +33 -0
  3. data/Manifest.txt +56 -0
  4. data/README +0 -0
  5. data/Rakefile +149 -0
  6. data/install.rb +30 -0
  7. data/lib/base.rb +12 -0
  8. data/lib/connection_adapters/abstract/schema_statements.rb +0 -0
  9. data/lib/connection_adapters/abstract_adapter.rb +32 -0
  10. data/lib/connection_adapters/mysql_adapter.rb +42 -0
  11. data/lib/connection_adapters/postgresql_adapter.rb +45 -0
  12. data/lib/dr_nic_magic_models/inflector.rb +14 -0
  13. data/lib/dr_nic_magic_models/magic_model.rb +135 -0
  14. data/lib/dr_nic_magic_models/schema.rb +270 -0
  15. data/lib/dr_nic_magic_models/validations.rb +46 -0
  16. data/lib/dr_nic_magic_models/version.rb +9 -0
  17. data/lib/dr_nic_magic_models.rb +34 -0
  18. data/lib/module.rb +33 -0
  19. data/lib/rails.rb +19 -0
  20. data/scripts/txt2html +66 -0
  21. data/scripts/txt2js +58 -0
  22. data/test/abstract_unit.rb +70 -0
  23. data/test/connections/native_mysql/connection.rb +14 -0
  24. data/test/connections/native_postgresql/connection.rb +12 -0
  25. data/test/connections/native_sqlite/connection.rb +10 -0
  26. data/test/dummy_test.rb +13 -0
  27. data/test/env_test.rb +10 -0
  28. data/test/fixtures/.DS_Store +0 -0
  29. data/test/fixtures/adjectives.yml +3 -0
  30. data/test/fixtures/adjectives_fun_users.yml +3 -0
  31. data/test/fixtures/db_definitions/mysql.drop.sql +4 -0
  32. data/test/fixtures/db_definitions/mysql.sql +58 -0
  33. data/test/fixtures/db_definitions/postgresql.sql +56 -0
  34. data/test/fixtures/db_definitions/sqlite.sql +49 -0
  35. data/test/fixtures/fun_users.yml +14 -0
  36. data/test/fixtures/group_memberships.yml +4 -0
  37. data/test/fixtures/group_tag.yml +11 -0
  38. data/test/fixtures/groups.yml +12 -0
  39. data/test/foreign_keys_test.rb +0 -0
  40. data/test/fun_user_plus.rb +2 -0
  41. data/test/invisible_model_access_test.rb +71 -0
  42. data/test/invisible_model_assoc_test.rb +61 -0
  43. data/test/invisible_model_classes_test.rb +23 -0
  44. data/test/magic_module_test.rb +20 -0
  45. data/test/test_existing_model.rb +20 -0
  46. data/test.db +0 -0
  47. data/website/index.html +409 -0
  48. data/website/index.txt +291 -0
  49. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  50. data/website/stylesheets/screen.css +106 -0
  51. data/website/template.js +3 -0
  52. data/website/template.rhtml +55 -0
  53. data/website/version-raw.js +3 -0
  54. data/website/version-raw.txt +2 -0
  55. data/website/version.js +4 -0
  56. data/website/version.txt +3 -0
  57. metadata +123 -0
@@ -0,0 +1,409 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
+ <head>
5
+ <link rel="stylesheet" href="stylesheets/screen.css" type="text/css" media="screen" />
6
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
+ <title>
8
+ Dr Nic&#8217;s Magic Models
9
+ </title>
10
+ <script src="javascripts/rounded_corners_lite.inc.js" type="text/javascript"></script>
11
+ <style>
12
+
13
+ </style>
14
+ <script type="text/javascript" src="version-raw.js"></script>
15
+ <script type="text/javascript">
16
+ window.onload = function() {
17
+ settings = {
18
+ tl: { radius: 10 },
19
+ tr: { radius: 10 },
20
+ bl: { radius: 10 },
21
+ br: { radius: 10 },
22
+ antiAlias: true,
23
+ autoPad: true,
24
+ validTags: ["div"]
25
+ }
26
+ var versionBox = new curvyCorners(settings, document.getElementById("version"));
27
+ versionBox.applyCornersToAll();
28
+
29
+ document.getElementById("version_num").innerHTML = version;
30
+ }
31
+ </script>
32
+ </head>
33
+ <body>
34
+ <div id="main">
35
+ <p><a href="/">&#x21A9; More Magic</a></p>
36
+
37
+ <div id="version" class="clickable" onclick='document.location = "http://rubyforge.org/projects/magicmodels"; return false'>
38
+ Get Version
39
+ <a id="version_num" href="http://rubyforge.org/projects/magicmodels" class="numbers"></a>
40
+ </div>
41
+ <h1>Dr Nic&#8217;s Magic Models</h1>
42
+ <p>If you&#8217;ve used Ruby on Rails you&#8217;ll have written at least one model class like this:</p>
43
+
44
+ <div class="ads" style="float: right">
45
+ <h4>Sponsors</h4>
46
+ <div id="mocra_ad_div"></div>
47
+ </div>
48
+
49
+ <p><pre class="syntax">
50
+ <span class="keyword">class </span><span class="class">Person</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>
51
+ <span class="ident">has_many</span> <span class="symbol">:memberships</span>
52
+ <span class="ident">has_many</span> <span class="symbol">:groups</span><span class="punct">,</span> <span class="symbol">:through</span> <span class="punct">=&gt;</span> <span class="symbol">:memberships</span>
53
+ <span class="ident">belongs_to</span> <span class="symbol">:family</span>
54
+ <span class="ident">validates_presence_of</span> <span class="symbol">:firstname</span><span class="punct">,</span> <span class="symbol">:lastname</span><span class="punct">,</span> <span class="symbol">:email</span>
55
+ <span class="keyword">end</span>
56
+ </pre></p>
57
+
58
+
59
+ <p>A few minutes later you&#8217;ll have wondered to yourself,</p>
60
+
61
+
62
+ <blockquote>
63
+ Why do I have write my own <code>has_many</code>, <code>belongs_to</code>, and <code>validates_presence_of</code>
64
+ commands if all the data is in the database schema?
65
+ </blockquote>
66
+
67
+ <p>Now, for the very first time, your classes can look like this:</p>
68
+
69
+
70
+ <p><pre class="syntax">
71
+ <span class="keyword">class </span><span class="class">Person</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>
72
+ <span class="keyword">end</span>
73
+ </pre></p>
74
+
75
+
76
+ <p>or, if you are lazy&#8230;</p>
77
+
78
+
79
+ <p><pre class="syntax">
80
+ <span class="keyword">class </span><span class="class">Person</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span><span class="punct">;</span> <span class="keyword">end</span>
81
+ </pre></p>
82
+
83
+
84
+ <p>or, if you read right to the end of this page, this&#8230;</p>
85
+
86
+
87
+ <p><pre class="syntax">
88
+ <span class="comment"># Go fish.</span>
89
+ </pre></p>
90
+
91
+
92
+ <p>Magic and mystery abound. All for you. Impress your friends, amaze your mother.</p>
93
+
94
+
95
+ <p><span class="caps">NOTE</span>: The gratuitous use of <strong>Dr Nic&#8217;s</strong> in the name should only enhance the mystical magikery,
96
+ for magic needs a magician; and I love magic. I always wanted to create my own magic trick.
97
+ So I shall be the magician for the sake of magic itself. I look a bit like Harry Potter too,
98
+ if Harry were 32 and better dressed.</p>
99
+
100
+
101
+ <h2>Installation</h2>
102
+
103
+
104
+ To install the Dr Nic&#8217;s Magic Models gem you can run the following command to
105
+ fetch the gem remotely from RubyForge:
106
+ <pre>
107
+ gem install dr_nic_magic_models
108
+ </pre>
109
+
110
+ <p>or <a href="http://rubyforge.org/projects/magicmodels">download the gem manually</a> and
111
+ run the above command in the download directory.</p>
112
+
113
+
114
+ <p>Now you need to <code>require</code> the gem into your Ruby/Rails app. Insert the following
115
+ line into your script (use <code>config/environment.rb</code> for your Rails apps):</p>
116
+
117
+
118
+ <pre>
119
+ require 'dr_nic_magic_models'
120
+ </pre>
121
+
122
+ <p>Your application is now blessed with magical mystery.</p>
123
+
124
+
125
+ <h2>David Copperfield eat your Ruby-crusted heart out</h2>
126
+
127
+
128
+ <p>Let&#8217;s demonstrate the magical mystery in all its full-stage glory. Create a Ruby on Rails app (example uses sqlite3, but use your favourite databas):</p>
129
+
130
+
131
+ <p><pre class="syntax">
132
+ <span class="ident">rails</span> <span class="ident">magic_show</span> <span class="punct">-</span><span class="ident">d</span> <span class="ident">sqlite3</span>
133
+ <span class="ident">cd</span> <span class="ident">magic_show</span>
134
+ <span class="ident">ruby</span> <span class="ident">script</span><span class="punct">/</span><span class="ident">generate</span> <span class="ident">model</span> <span class="constant">Person</span>
135
+ <span class="ident">ruby</span> <span class="ident">script</span><span class="punct">/</span><span class="ident">generate</span> <span class="ident">model</span> <span class="constant">Group</span>
136
+ <span class="ident">ruby</span> <span class="ident">script</span><span class="punct">/</span><span class="ident">generate</span> <span class="ident">model</span> <span class="constant">Membership</span>
137
+ </pre></p>
138
+
139
+
140
+ <p>Update the migration <code>001_create_people.rb</code> with:
141
+ <pre class="syntax">
142
+ <span class="keyword">class </span><span class="class">CreatePeople</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Migration</span>
143
+ <span class="keyword">def </span><span class="method">self.up</span>
144
+ <span class="ident">create_table</span> <span class="symbol">:people</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">t</span><span class="punct">|</span>
145
+ <span class="ident">t</span><span class="punct">.</span><span class="ident">column</span> <span class="symbol">:firstname</span><span class="punct">,</span> <span class="symbol">:string</span><span class="punct">,</span> <span class="symbol">:null</span> <span class="punct">=&gt;</span> <span class="constant">false</span>
146
+ <span class="ident">t</span><span class="punct">.</span><span class="ident">column</span> <span class="symbol">:lastname</span><span class="punct">,</span> <span class="symbol">:string</span><span class="punct">,</span> <span class="symbol">:null</span> <span class="punct">=&gt;</span> <span class="constant">false</span>
147
+ <span class="ident">t</span><span class="punct">.</span><span class="ident">column</span> <span class="symbol">:email</span><span class="punct">,</span> <span class="symbol">:string</span><span class="punct">,</span> <span class="symbol">:null</span> <span class="punct">=&gt;</span> <span class="constant">false</span>
148
+ <span class="keyword">end</span>
149
+ <span class="keyword">end</span>
150
+
151
+ <span class="keyword">def </span><span class="method">self.down</span>
152
+ <span class="ident">drop_table</span> <span class="symbol">:people</span>
153
+ <span class="keyword">end</span>
154
+ <span class="keyword">end</span>
155
+ </pre></p>
156
+
157
+
158
+ <p>Similarly, update the <code>def self.up</code> method of <code>002_create_groups.rb</code>
159
+ with:
160
+ <pre class="syntax">
161
+ <span class="ident">create_table</span> <span class="symbol">:groups</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">t</span><span class="punct">|</span>
162
+ <span class="ident">t</span><span class="punct">.</span><span class="ident">column</span> <span class="symbol">:name</span><span class="punct">,</span> <span class="symbol">:string</span><span class="punct">,</span> <span class="symbol">:null</span> <span class="punct">=&gt;</span> <span class="constant">false</span>
163
+ <span class="ident">t</span><span class="punct">.</span><span class="ident">column</span> <span class="symbol">:description</span><span class="punct">,</span> <span class="symbol">:string</span>
164
+ <span class="keyword">end</span>
165
+ </pre></p>
166
+
167
+
168
+ <p>and <code>003_create_memberships.rb</code> with:
169
+ <pre class="syntax">
170
+ <span class="ident">create_table</span> <span class="symbol">:memberships</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">t</span><span class="punct">|</span>
171
+ <span class="ident">t</span><span class="punct">.</span><span class="ident">column</span> <span class="symbol">:person_id</span><span class="punct">,</span> <span class="symbol">:integer</span><span class="punct">,</span> <span class="symbol">:null</span> <span class="punct">=&gt;</span> <span class="constant">false</span>
172
+ <span class="ident">t</span><span class="punct">.</span><span class="ident">column</span> <span class="symbol">:group_id</span><span class="punct">,</span> <span class="symbol">:integer</span><span class="punct">,</span> <span class="symbol">:null</span> <span class="punct">=&gt;</span> <span class="constant">false</span>
173
+ <span class="keyword">end</span>
174
+ </pre></p>
175
+
176
+
177
+ And run your migrations to create the three tables:
178
+ <pre>
179
+ rake db:migrate
180
+ </pre>
181
+
182
+ <h3>And now for some <a href="http://en.wikipedia.org/wiki/List_of_conjuring_terms">woofle dust</a> ...</h3>
183
+
184
+
185
+ <p>At the end of <code>config/environment.rb</code> add the following line:</p>
186
+
187
+
188
+ <pre>
189
+ require 'dr_nic_magic_models'
190
+ </pre>
191
+
192
+ <p>Now, let&#8217;s do a magic trick. First, let&#8217;s check our model classes (<code>app/models/person.rb</code> etc):</p>
193
+
194
+
195
+ <p><pre class="syntax">
196
+ <span class="keyword">class </span><span class="class">Person</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>
197
+ <span class="keyword">end</span>
198
+ <span class="keyword">class </span><span class="class">Group</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>
199
+ <span class="keyword">end</span>
200
+ <span class="keyword">class </span><span class="class">Membership</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>
201
+ <span class="keyword">end</span>
202
+ </pre></p>
203
+
204
+
205
+ <p>Nothing suspicious here. We have no validations and no associations. Just some plain old model classes.</p>
206
+
207
+
208
+ <p><span class="caps">UPDATE</span>: To turn on magic validations, you now need to invoke <code>generate_validations</code> on defined classes. So, update your model classes:</p>
209
+
210
+
211
+ <p><pre class="syntax">
212
+ <span class="keyword">class </span><span class="class">Person</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>
213
+ <span class="ident">generate_validations</span>
214
+ <span class="keyword">end</span>
215
+ <span class="keyword">class </span><span class="class">Group</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>
216
+ <span class="ident">generate_validations</span>
217
+ <span class="keyword">end</span>
218
+ <span class="keyword">class </span><span class="class">Membership</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>
219
+ <span class="ident">generate_validations</span>
220
+ <span class="keyword">end</span>
221
+ </pre></p>
222
+
223
+
224
+ <p>For this trick, we&#8217;ll need an ordinary console session. Any old one lying around the house will do.</p>
225
+
226
+
227
+ <pre>
228
+ ruby script/console
229
+ </pre>
230
+
231
+ <p>Now a normal model class is valid until you explicitly add <code>validates_xxx</code> commands.
232
+ With Dr Nic&#8217;s Magic Models:</p>
233
+
234
+
235
+ <p><pre class="syntax">
236
+ <span class="ident">person</span> <span class="punct">=</span> <span class="constant">Person</span><span class="punct">.</span><span class="ident">new</span>
237
+ <span class="punct">=&gt;</span> <span class="comment">#&lt;Person:0x393e0f8 @attributes={&quot;lastname&quot;=&gt;&quot;&quot;, &quot;firstname&quot;=&gt;&quot;&quot;, &quot;email&quot;=&gt;&quot;&quot;}, @new_record=true&gt;</span>
238
+ <span class="ident">person</span><span class="punct">.</span><span class="ident">valid?</span>
239
+ <span class="punct">=&gt;</span> <span class="constant">false</span>
240
+ <span class="ident">person</span><span class="punct">.</span><span class="ident">errors</span>
241
+ <span class="punct">=&gt;</span> <span class="comment">#&lt;ActiveRecord::Errors:0x3537b38 @errors={</span>
242
+ <span class="punct">&quot;</span><span class="string">firstname</span><span class="punct">&quot;=&gt;[&quot;</span><span class="string">can't be blank</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">is too long (maximum is 255 characters)</span><span class="punct">&quot;],</span>
243
+ <span class="punct">&quot;</span><span class="string">lastname</span><span class="punct">&quot;=&gt;[&quot;</span><span class="string">can't be blank</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">is too long (maximum is 255 characters)</span><span class="punct">&quot;],</span>
244
+ <span class="punct">&quot;</span><span class="string">email</span><span class="punct">&quot;=&gt;[&quot;</span><span class="string">can't be blank</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">is too long (maximum is 255 characters)</span><span class="punct">&quot;]},</span>
245
+ <span class="attribute">@base</span><span class="punct">=</span><span class="comment">#&lt;Person:0x3538bf0 @errors=#&lt;ActiveRecord::Errors:0x3537b38 ...&gt;, @new_record=true, </span>
246
+ <span class="attribute">@attributes</span><span class="punct">={&quot;</span><span class="string">lastname</span><span class="punct">&quot;=&gt;</span><span class="constant">nil</span><span class="punct">,</span> <span class="punct">&quot;</span><span class="string">firstname</span><span class="punct">&quot;=&gt;</span><span class="constant">nil</span><span class="punct">,</span> <span class="punct">&quot;</span><span class="string">email</span><span class="punct">&quot;=&gt;</span><span class="constant">nil</span><span class="punct">}&gt;&gt;</span>
247
+ </pre></p>
248
+
249
+
250
+ <p><strong>Kapoow!</strong> Instant validation! (NOTE: not as instant as it used to be &#8211; remember &#8211; you need to call <code>generate_validations</code> on each class as required)</p>
251
+
252
+
253
+ <p>Because you specified the three columns as <code>:null =&gt; false</code>,
254
+ your ActiveRecord models will now automagically generated <code>validates_presence_of</code>
255
+ for each non-null field, plus several other validations (since version 0.8.0).</p>
256
+
257
+
258
+ <p>Ok, we&#8217;re just warming up.</p>
259
+
260
+
261
+ <p>Your models normally require association commands (<code>has_many</code>, <code>belongs_to</code>, etc, as
262
+ demonstrated above) to have the brilliantly simple support that Rails/ActiveRecords are known for.</p>
263
+
264
+
265
+ <p>Let&#8217;s just watch what Dr Nic&#8217;s Magic Models can do without any effort at all&#8230;</p>
266
+
267
+
268
+ <p><pre class="syntax">
269
+ <span class="ident">person</span> <span class="punct">=</span> <span class="constant">Person</span><span class="punct">.</span><span class="ident">create</span><span class="punct">(</span><span class="symbol">:firstname</span> <span class="punct">=&gt;</span> <span class="punct">&quot;</span><span class="string">Nic</span><span class="punct">&quot;,</span> <span class="symbol">:lastname</span> <span class="punct">=&gt;</span> <span class="punct">&quot;</span><span class="string">Williams</span><span class="punct">&quot;,</span> <span class="symbol">:email</span> <span class="punct">=&gt;</span> <span class="punct">&quot;</span><span class="string">drnicwilliams@gmail.com</span><span class="punct">&quot;)</span>
270
+ <span class="ident">group</span> <span class="punct">=</span> <span class="constant">Group</span><span class="punct">.</span><span class="ident">create</span><span class="punct">(</span><span class="symbol">:name</span> <span class="punct">=&gt;</span> <span class="punct">&quot;</span><span class="string">Magic Models Forum</span><span class="punct">&quot;,</span> <span class="symbol">:description</span> <span class="punct">=&gt;</span> <span class="punct">&quot;</span><span class="string">http://groups.google.com/magicmodels</span><span class="punct">&quot;)</span>
271
+ <span class="ident">membership</span> <span class="punct">=</span> <span class="constant">Membership</span><span class="punct">.</span><span class="ident">create</span><span class="punct">(</span><span class="symbol">:person</span> <span class="punct">=&gt;</span> <span class="ident">person</span><span class="punct">,</span> <span class="symbol">:group</span> <span class="punct">=&gt;</span> <span class="ident">group</span><span class="punct">)</span>
272
+ <span class="ident">person</span><span class="punct">.</span><span class="ident">memberships</span><span class="punct">.</span><span class="ident">length</span>
273
+ <span class="punct">=&gt;</span> <span class="number">1</span>
274
+ <span class="ident">membership</span><span class="punct">.</span><span class="ident">person</span>
275
+ <span class="punct">=&gt;</span> <span class="punct">&lt;</span><span class="constant">Person</span><span class="punct">:</span><span class="number">0x38898e8</span> <span class="attribute">@attributes</span><span class="punct">={&quot;</span><span class="string">lastname</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">Williams</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">firstname</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">Nic</span><span class="punct">&quot;,</span>
276
+ <span class="punct">&quot;</span><span class="string">id</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">1</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">email</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">drnicwilliams@gmail.com</span><span class="punct">&quot;}&gt;</span>
277
+ <span class="ident">group</span><span class="punct">.</span><span class="ident">memberships</span>
278
+ <span class="punct">=&gt;</span> <span class="punct">[&lt;</span><span class="constant">Membership</span><span class="punct">:</span><span class="number">0x3c8cd70</span> <span class="attribute">@attributes</span><span class="punct">={&quot;</span><span class="string">group_id</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">1</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">id</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">1</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">person_id</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">1</span><span class="punct">&quot;}&gt;]</span>
279
+ </pre></p>
280
+
281
+
282
+ <p>That final association trick is a ripper. Automatic generation of <code>has_many :through</code> associations&#8230;</p>
283
+
284
+
285
+ <p><pre class="syntax">
286
+ <span class="punct">&gt;&gt;</span> <span class="ident">person</span><span class="punct">.</span><span class="ident">groups</span>
287
+ <span class="punct">=&gt;</span> <span class="punct">[&lt;</span><span class="constant">Group</span><span class="punct">:</span><span class="number">0x39047e0</span> <span class="attribute">@attributes</span><span class="punct">={&quot;</span><span class="string">name</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">Magic Models Forum</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">id</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">1</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">description</span><span class="punct">&quot;=&gt;</span><span class="constant">nil</span><span class="punct">}&gt;]</span>
288
+ <span class="punct">&gt;&gt;</span> <span class="ident">group</span><span class="punct">.</span><span class="ident">people</span>
289
+ <span class="punct">=&gt;</span> <span class="punct">[&lt;</span><span class="constant">Person</span><span class="punct">:</span><span class="number">0x3c33580</span> <span class="attribute">@attributes</span><span class="punct">={&quot;</span><span class="string">lastname</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">Williams</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">firstname</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">Nic</span><span class="punct">&quot;,</span>
290
+ <span class="punct">&quot;</span><span class="string">id</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">1</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">email</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">drnicwilliams@gmail.com</span><span class="punct">&quot;}&gt;]</span>
291
+ </pre></p>
292
+
293
+
294
+ <h3>Drum roll&#8230;</h3>
295
+
296
+
297
+ <p>Ladies and gentlemen. For my final feat of magical mastery, I&#8217;ll ask you to do
298
+ something you&#8217;ve never done before. This illusion is akin to the <a href="http://www.toytent.com/Posters/985.html">floating lady</a>
299
+ illusion that has been passed down through generations of magicians.</p>
300
+
301
+
302
+ <p>Exit your console session.</p>
303
+
304
+
305
+ <span class="caps">DELETE</span> your three model classes: <code>person.rb, group.rb, and membership.rb</code> from the
306
+ <code>app/models</code> folder. (You can always get them back via the model generator&#8230; be fearless!)
307
+
308
+ <pre>rm app/models/*.rb</pre>
309
+
310
+ <p>Re-launch your console.</p>
311
+
312
+
313
+ <p><strong>drums are still rolling&#8230;</strong></p>
314
+
315
+
316
+ <p>Be prepared to applaud loudly&#8230;</p>
317
+
318
+
319
+ <p><pre class="syntax">
320
+ <span class="punct">&gt;&gt;</span> <span class="constant">Person</span>
321
+ <span class="punct">=&gt;</span> <span class="constant">Person</span>
322
+ </pre></p>
323
+
324
+
325
+ <p>You applaud loudly, but watch for more&#8230;</p>
326
+
327
+
328
+ <p><pre class="syntax">
329
+ <span class="punct">&gt;&gt;</span> <span class="constant">Person</span><span class="punct">.</span><span class="ident">new</span><span class="punct">.</span><span class="ident">valid?</span>
330
+ <span class="punct">=&gt;</span> <span class="constant">false</span>
331
+ <span class="punct">&gt;&gt;</span> <span class="ident">person</span> <span class="punct">=</span> <span class="constant">Person</span><span class="punct">.</span><span class="ident">find</span><span class="punct">(</span><span class="number">1</span><span class="punct">)</span>
332
+ <span class="punct">=&gt;</span> <span class="punct">&lt;</span><span class="constant">Person</span><span class="punct">:</span><span class="number">0x3958930</span> <span class="attribute">@attributes</span><span class="punct">={&quot;</span><span class="string">lastname</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">Williams</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">firstname</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">Nic</span><span class="punct">&quot;,</span>
333
+ <span class="punct">&quot;</span><span class="string">id</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">1</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">email</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">drnicwilliams@gmail.com</span><span class="punct">&quot;}&gt;</span>
334
+ <span class="punct">&gt;&gt;</span> <span class="ident">person</span><span class="punct">.</span><span class="ident">valid?</span>
335
+ <span class="punct">=&gt;</span> <span class="constant">true</span>
336
+ <span class="punct">&gt;&gt;</span> <span class="ident">person</span><span class="punct">.</span><span class="ident">memberships</span>
337
+ <span class="punct">=&gt;</span> <span class="punct">[&lt;</span><span class="constant">Membership</span><span class="punct">:</span><span class="number">0x393a000</span> <span class="attribute">@attributes</span><span class="punct">={&quot;</span><span class="string">group_id</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">1</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">id</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">1</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">person_id</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">1</span><span class="punct">&quot;}&gt;]</span>
338
+ <span class="punct">&gt;&gt;</span> <span class="ident">person</span><span class="punct">.</span><span class="ident">groups</span>
339
+ <span class="punct">=&gt;</span> <span class="punct">[&lt;</span><span class="constant">Group</span><span class="punct">:</span><span class="number">0x390df60</span> <span class="attribute">@attributes</span><span class="punct">={&quot;</span><span class="string">name</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">Magic Models Forum</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">id</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">1</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">description</span><span class="punct">&quot;=&gt;</span><span class="constant">nil</span><span class="punct">}&gt;]</span>
340
+ </pre></p>
341
+
342
+
343
+ <h3>Tada!</h3>
344
+
345
+
346
+ <p>The end.</p>
347
+
348
+
349
+ <h3>Use modules to scope your magic</h3>
350
+
351
+
352
+ <p>Only want to pick up tables starting with <code>blog_</code>?</p>
353
+
354
+
355
+ <p><pre class="syntax"><span class="keyword">module </span><span class="module">Blog</span>
356
+ <span class="ident">magic_module</span> <span class="symbol">:table_name_prefix</span> <span class="punct">=&gt;</span> <span class="punct">'</span><span class="string">blog_</span><span class="punct">'</span>
357
+ <span class="keyword">end</span>
358
+
359
+ <span class="constant">Blog</span><span class="punct">::</span><span class="constant">Post</span><span class="punct">.</span><span class="ident">table_name</span> <span class="comment"># =&gt; 'blog_posts'</span>
360
+ </pre></p>
361
+
362
+
363
+ <h2>Dr Nic&#8217;s Blog</h2>
364
+
365
+
366
+ <p><a href="http://www.drnicwilliams.com">http://www.drnicwilliams.com</a> &#8211; for future announcements and
367
+ other stories and things.</p>
368
+
369
+
370
+ <h2>Articles about Magic Models</h2>
371
+
372
+
373
+ <ul>
374
+ <li><a href="http://drnicwilliams.com/2006/08/07/ann-dr-nics-magic-models/">Announcement</a></li>
375
+ <li><a href="http://drnicwilliams.com/2006/08/10/bts-magic-models-class-creation/"><span class="caps">BTS</span> &#8211; Class creation</a></li>
376
+ </ul>
377
+
378
+
379
+ <h2>Forum</h2>
380
+
381
+
382
+ <p><a href="http://groups.google.com/group/magicmodels">http://groups.google.com/group/magicmodels</a></p>
383
+
384
+
385
+ <h2>Licence</h2>
386
+
387
+
388
+ <p>This code is free to use under the terms of the <span class="caps">MIT</span> licence.</p>
389
+
390
+
391
+ <h2>Contact</h2>
392
+
393
+
394
+ <p>Comments are welcome. Send an email to <a href="mailto:drnicwilliams@gmail.com">Dr Nic Williams</a>
395
+ or via his blog at <a href="http://www.drnicwilliams.com">http://www.drnicwilliams.com</a></p>
396
+ <p class="coda">
397
+ <a href="mailto:drnicwilliams@gmail.com">Dr Nic</a>, 30th April 2007<br>
398
+ Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
399
+ </p>
400
+ </div>
401
+ <script src="http://ads.mocra.com/sites/pastie.js" type="text/javascript">
402
+ <script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
403
+ </script>
404
+ <script type="text/javascript">
405
+ _uacct = "UA-567811-3";
406
+ urchinTracker();
407
+ </script>
408
+ </body>
409
+ </html>