dr_nic_magic_models 0.9.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,10 +1,19 @@
1
+ *** 0.9.1 / 2007-4-11
2
+
3
+ + 1 minor enhancement:
4
+ + ActiveRecord::Base includes all the magic model functionality via the MagicModel module
5
+ + Existing ARs can get magic validation via #generate_validations call
6
+ + Website tutorial works :D
7
+
1
8
  *** 0.9.0 / 2007-4-9
2
9
 
3
10
  + 1 major enhancement:
4
11
  + Support for dynamic loading of classes again
5
12
  + 2 new DB supported:
6
13
  + Tests run on sqlite (no fk support)
7
- + Tests run on postgresql (fk support)
14
+ + Tests run on postgresql (fk support)
15
+ + Including FK bug fix
8
16
  + Many fixes that I've lost track of
9
17
  + History.txt to keep track of changes like these
10
18
  + Using Hoe for Rakefile
19
+ + Use modules to specify common table prefixes
data/Manifest.txt CHANGED
@@ -43,6 +43,7 @@ test/invisible_model_access_test.rb
43
43
  test/invisible_model_assoc_test.rb
44
44
  test/invisible_model_classes_test.rb
45
45
  test/magic_module_test.rb
46
+ test/test_existing_model.rb
46
47
  website/index.html
47
48
  website/index.txt
48
49
  website/javascripts/rounded_corners_lite.inc.js
data/README CHANGED
@@ -1,7 +1,6 @@
1
1
  See http://magicmodels.rubyforge.org/dr_nic_magic_models for pretty README
2
2
 
3
3
  Ugly README (from website/index.txt in Textile format):
4
-
5
4
  h1. Dr Nic's Magic Models
6
5
 
7
6
  If you've used Ruby on Rails you'll have written at least one model class like this:
@@ -70,10 +69,10 @@ Your application is now blessed with magical mystery.
70
69
 
71
70
  h2. David Copperfield eat your Ruby-crusted heart out
72
71
 
73
- Let's demonstrate the magical mystery in all its full-stage glory. Create a Ruby on Rails app:
72
+ Let'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):
74
73
 
75
74
  <pre syntax="ruby">
76
- rails magic_show
75
+ rails magic_show -d sqlite3
77
76
  cd magic_show
78
77
  ruby script/generate model Person
79
78
  ruby script/generate model Group
@@ -114,18 +113,12 @@ and <code>003_create_memberships.rb</code> with:
114
113
  end
115
114
  </pre>
116
115
 
117
- Now create your database. For MySql:
118
- <pre>
119
- mysqladmin -u root create magic_show_development
120
- mysqladmin -u root create magic_show_test
121
- </pre>
122
-
123
116
  And run your migrations to create the three tables:
124
117
  <pre>
125
- rake migrate
118
+ rake db:migrate
126
119
  </pre>
127
120
 
128
- h2. And now for some "woofle dust":http://en.wikipedia.org/wiki/List_of_conjuring_terms ...
121
+ h3. And now for some "woofle dust":http://en.wikipedia.org/wiki/List_of_conjuring_terms ...
129
122
 
130
123
  At the end of <code>config/environment.rb</code> add the following line:
131
124
 
@@ -146,6 +139,20 @@ end
146
139
 
147
140
  Nothing suspicious here. We have no validations and no associations. Just some plain old model classes.
148
141
 
142
+ UPDATE: To turn on magic validations, you now need to invoke <code>generate_validations</code> on defined classes. So, update your model classes:
143
+
144
+ <pre syntax="ruby">
145
+ class Person < ActiveRecord::Base
146
+ generate_validations
147
+ end
148
+ class Group < ActiveRecord::Base
149
+ generate_validations
150
+ end
151
+ class Membership < ActiveRecord::Base
152
+ generate_validations
153
+ end
154
+ </pre>
155
+
149
156
  For this trick, we'll need an ordinary console session. Any old one lying around the house will do.
150
157
 
151
158
  <pre>
@@ -156,22 +163,24 @@ Now a normal model class is valid until you explicitly add <code>validates_xxx</
156
163
  With Dr Nic's Magic Models:
157
164
 
158
165
  <pre syntax="ruby">
159
- >> person = Person.new
166
+ person = Person.new
160
167
  => #<Person:0x393e0f8 @attributes={"lastname"=>"", "firstname"=>"", "email"=>""}, @new_record=true>
161
- >> person.valid?
168
+ person.valid?
162
169
  => false
163
- >> person.errors
164
- => <ActiveRecord::Errors:0x3938b18 @errors={"firstname"=>["can't be blank"],
165
- "lastname"=>["can't be blank"], "email"=>["can't be blank"]},
166
- @base=<Person:0x393e0f8 @errors=<ActiveRecord::Errors:0x3938b18 ...>,
167
- @attributes={"lastname"=>"", "firstname"=>"", "email"=>""}, @new_record=true>>
170
+ person.errors
171
+ => #<ActiveRecord::Errors:0x3537b38 @errors={
172
+ "firstname"=>["can't be blank", "is too long (maximum is 255 characters)"],
173
+ "lastname"=>["can't be blank", "is too long (maximum is 255 characters)"],
174
+ "email"=>["can't be blank", "is too long (maximum is 255 characters)"]},
175
+ @base=#<Person:0x3538bf0 @errors=#<ActiveRecord::Errors:0x3537b38 ...>, @new_record=true,
176
+ @attributes={"lastname"=>nil, "firstname"=>nil, "email"=>nil}>>
168
177
  </pre>
169
178
 
170
- *Kapoow!* Instant validation!
179
+ *Kapoow!* Instant validation! (NOTE: not as instant as it used to be - remember - you need to call <code>generate_validations</code> on each class as required)
171
180
 
172
181
  Because you specified the three columns as <code>:null => false</code>,
173
- your ActiveRecord models will now automatically generated <code>validates_presence_of</code>
174
- for each non-null field.
182
+ your ActiveRecord models will now automagically generated <code>validates_presence_of</code>
183
+ for each non-null field, plus several other validations (since version 0.8.0).
175
184
 
176
185
  Ok, we're just warming up.
177
186
 
@@ -181,15 +190,15 @@ demonstrated above) to have the brilliantly simple support that Rails/ActiveReco
181
190
  Let's just watch what Dr Nic's Magic Models can do without any effort at all...
182
191
 
183
192
  <pre syntax="ruby">
184
- >> person = Person.create(:firstname => "Nic", :lastname => "Williams", :email => "drnicwilliams@gmail.com")
185
- >> group = Group.create(:name => "Magic Models Forum", :description => "http://groups.google.com/magicmodels")
186
- >> membership = Membership.create(:person_id => person, :group_id => group)
187
- >> person.memberships.length
193
+ person = Person.create(:firstname => "Nic", :lastname => "Williams", :email => "drnicwilliams@gmail.com")
194
+ group = Group.create(:name => "Magic Models Forum", :description => "http://groups.google.com/magicmodels")
195
+ membership = Membership.create(:person => person, :group => group)
196
+ person.memberships.length
188
197
  => 1
189
- >> membership.person
198
+ membership.person
190
199
  => <Person:0x38898e8 @attributes={"lastname"=>"Williams", "firstname"=>"Nic",
191
200
  "id"=>"1", "email"=>"drnicwilliams@gmail.com"}>
192
- >> group.memberships
201
+ group.memberships
193
202
  => [<Membership:0x3c8cd70 @attributes={"group_id"=>"1", "id"=>"1", "person_id"=>"1"}>]
194
203
  </pre>
195
204
 
@@ -204,7 +213,7 @@ The final association trick is a ripper. Automatic generation of <code>has_many
204
213
  "id"=>"1", "email"=>"drnicwilliams@gmail.com"}>]
205
214
  </pre>
206
215
 
207
- h2. Drum roll...
216
+ h3. Drum roll...
208
217
 
209
218
  Ladies and gentlemen. For my final feat of magical mastery, I'll ask you to do
210
219
  something you've never done before. This illusion is akin to the "floating lady":http://www.toytent.com/Posters/985.html
@@ -215,6 +224,8 @@ Exit your console session.
215
224
  DELETE your three model classes: <code>person.rb, group.rb, and membership.rb</code> from the
216
225
  <code>app/models</code> folder. (You can always get them back via the model generator... be fearless!)
217
226
 
227
+ <pre>rm app/models/*.rb</pre>
228
+
218
229
  Re-launch your console.
219
230
 
220
231
  *drums are still rolling...*
@@ -229,19 +240,34 @@ Be prepared to applaud loudly...
229
240
  You applaud loudly, but watch for more...
230
241
 
231
242
  <pre syntax="ruby">
243
+ >> Person.new.valid?
244
+ => false
232
245
  >> person = Person.find(1)
233
246
  => <Person:0x3958930 @attributes={"lastname"=>"Williams", "firstname"=>"Nic",
234
247
  "id"=>"1", "email"=>"drnicwilliams@gmail.com"}>
248
+ >> person.valid?
249
+ => true
235
250
  >> person.memberships
236
251
  => [<Membership:0x393a000 @attributes={"group_id"=>"1", "id"=>"1", "person_id"=>"1"}>]
237
252
  >> person.groups
238
253
  => [<Group:0x390df60 @attributes={"name"=>"Magic Models Forum", "id"=>"1", "description"=>nil}>]
239
254
  </pre>
240
255
 
241
- h2. Tada!
256
+ h3. Tada!
242
257
 
243
258
  The end.
244
259
 
260
+ h3. Use modules to scope your magic
261
+
262
+ Only want to pick up tables starting with <code>blog_</code>?
263
+
264
+ <pre syntax="ruby">module Blog
265
+ magic_module :table_name_prefix => 'blog_'
266
+ end
267
+
268
+ Blog::Post.table_name # => 'blog_posts'
269
+ </pre>
270
+
245
271
  h2. Dr Nic's Blog
246
272
 
247
273
  "http://www.drnicwilliams.com":http://www.drnicwilliams.com - for future announcements and
@@ -53,9 +53,11 @@ module DrNicMagicModels::MagicModel
53
53
  rescue NotImplementedError
54
54
  nil
55
55
  end
56
- if not fkc.nil? and fkc.length > 0
56
+ if !fkc.nil? && fkc.length > 0
57
57
  foreign_key = fkc.first.foreign_key
58
- options = {:dependent => :destroy, :foreign_key => fkc.first.foreign_key, :class_name => self.class.class_name(fkc.first.reference_table)}
58
+ options = {:dependent => :destroy,
59
+ :foreign_key => fkc.first.foreign_key,
60
+ :class_name => self.class.class_name(fkc.first.reference_table)}
59
61
  else
60
62
  foreign_key = self.class.columns.select {|column| column.name == method.to_s.foreign_key}.first
61
63
  end
@@ -2,7 +2,7 @@ module DrNicMagicModels #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 9
5
- TINY = 0
5
+ TINY = 1
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -28,4 +28,7 @@ require 'connection_adapters/postgresql_adapter'
28
28
  # load the schema
29
29
  # TODO - add this to README - DrNicMagicModels::Schema.load_schema(true)
30
30
 
31
-
31
+ class ActiveRecord::Base
32
+ include DrNicMagicModels::MagicModel
33
+ extend DrNicMagicModels::Validations
34
+ end
data/lib/module.rb CHANGED
@@ -13,21 +13,21 @@ class Module
13
13
  superklass = @magic_schema.superklass || ActiveRecord::Base
14
14
  klass = create_class(class_id, superklass) do
15
15
  set_table_name table_name
16
- include DrNicMagicModels::MagicModel
17
- extend DrNicMagicModels::Validations
16
+ # include DrNicMagicModels::MagicModel
17
+ # extend DrNicMagicModels::Validations
18
18
  end
19
19
  klass.generate_validations # need to call this AFTER the class name has been assigned
20
20
  @magic_schema.inflector.post_class_creation klass
21
21
  klass
22
22
  end
23
23
 
24
- def magic_module(table_name_prefix)
25
- self.instance_variable_set "@table_name_prefix", table_name_prefix
24
+ def magic_module(options)
25
+ self.instance_variable_set "@table_name_prefix", options[:table_name_prefix] if options[:table_name_prefix]
26
26
  end
27
27
 
28
28
  private
29
29
  def create_class(class_name, superclass, &block)
30
30
  klass = Class.new superclass, &block
31
- Object.const_set class_name, klass
31
+ self.const_set class_name, klass
32
32
  end
33
33
  end
@@ -1,7 +1,7 @@
1
1
  require 'abstract_unit'
2
2
 
3
3
  module MagicGroup
4
- magic_module 'group_'
4
+ magic_module :table_name_prefix => 'group_'
5
5
  end
6
6
 
7
7
  class MagicModuleTest < Test::Unit::TestCase
@@ -0,0 +1,20 @@
1
+ require 'abstract_unit'
2
+ require 'pp'
3
+
4
+ module TestBed
5
+ class Group < ActiveRecord::Base
6
+ generate_validations
7
+ end
8
+ end
9
+
10
+ class TestExistingModel < Test::Unit::TestCase
11
+ # fixtures :fun_users, :groups, :group_memberships, :group_tag
12
+
13
+ def setup
14
+ create_fixtures :fun_users, :groups, :group_memberships, :group_tag
15
+ end
16
+
17
+ def test_valid
18
+ assert(!TestBed::Group.new.valid?)
19
+ end
20
+ end
data/test.db CHANGED
Binary file
data/website/index.html CHANGED
@@ -32,12 +32,13 @@
32
32
  </head>
33
33
  <body>
34
34
  <div id="main">
35
+ <p><a href="/">&#x21A9; More Magic</a></p>
35
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>
36
41
  <h1>Dr Nic&#8217;s Magic Models</h1>
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
42
  <p>If you&#8217;ve used Ruby on Rails you&#8217;ll have written at least one model class like this:</p>
42
43
 
43
44
 
@@ -120,11 +121,11 @@ require 'dr_nic_magic_models'
120
121
  <h2>David Copperfield eat your Ruby-crusted heart out</h2>
121
122
 
122
123
 
123
- <p>Let&#8217;s demonstrate the magical mystery in all its full-stage glory. Create a Ruby on Rails app:</p>
124
+ <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>
124
125
 
125
126
 
126
127
  <p><pre class="syntax">
127
- <span class="ident">rails</span> <span class="ident">magic_show</span>
128
+ <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>
128
129
  <span class="ident">cd</span> <span class="ident">magic_show</span>
129
130
  <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>
130
131
  <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>
@@ -169,18 +170,12 @@ with:
169
170
  </pre></p>
170
171
 
171
172
 
172
- Now create your database. For MySql:
173
- <pre>
174
- mysqladmin -u root create magic_show_development
175
- mysqladmin -u root create magic_show_test
176
- </pre>
177
-
178
173
  And run your migrations to create the three tables:
179
174
  <pre>
180
- rake migrate
175
+ rake db:migrate
181
176
  </pre>
182
177
 
183
- <h2>And now for some <a href="http://en.wikipedia.org/wiki/List_of_conjuring_terms">woofle dust</a> ...</h2>
178
+ <h3>And now for some <a href="http://en.wikipedia.org/wiki/List_of_conjuring_terms">woofle dust</a> ...</h3>
184
179
 
185
180
 
186
181
  <p>At the end of <code>config/environment.rb</code> add the following line:</p>
@@ -206,6 +201,22 @@ require 'dr_nic_magic_models'
206
201
  <p>Nothing suspicious here. We have no validations and no associations. Just some plain old model classes.</p>
207
202
 
208
203
 
204
+ <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>
205
+
206
+
207
+ <p><pre class="syntax">
208
+ <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>
209
+ <span class="ident">generate_validations</span>
210
+ <span class="keyword">end</span>
211
+ <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>
212
+ <span class="ident">generate_validations</span>
213
+ <span class="keyword">end</span>
214
+ <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>
215
+ <span class="ident">generate_validations</span>
216
+ <span class="keyword">end</span>
217
+ </pre></p>
218
+
219
+
209
220
  <p>For this trick, we&#8217;ll need an ordinary console session. Any old one lying around the house will do.</p>
210
221
 
211
222
 
@@ -218,24 +229,26 @@ With Dr Nic&#8217;s Magic Models:</p>
218
229
 
219
230
 
220
231
  <p><pre class="syntax">
221
- <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">new</span>
232
+ <span class="ident">person</span> <span class="punct">=</span> <span class="constant">Person</span><span class="punct">.</span><span class="ident">new</span>
222
233
  <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>
223
- <span class="punct">&gt;&gt;</span> <span class="ident">person</span><span class="punct">.</span><span class="ident">valid?</span>
234
+ <span class="ident">person</span><span class="punct">.</span><span class="ident">valid?</span>
224
235
  <span class="punct">=&gt;</span> <span class="constant">false</span>
225
- <span class="punct">&gt;&gt;</span> <span class="ident">person</span><span class="punct">.</span><span class="ident">errors</span>
226
- <span class="punct">=&gt;</span> <span class="punct">&lt;</span><span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Errors</span><span class="punct">:</span><span class="number">0x3938b18</span> <span class="attribute">@errors</span><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>
227
- <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">email</span><span class="punct">&quot;=&gt;[&quot;</span><span class="string">can't be blank</span><span class="punct">&quot;]},</span>
228
- <span class="attribute">@base</span><span class="punct">=&lt;</span><span class="constant">Person</span><span class="punct">:</span><span class="number">0x393e0f8</span> <span class="attribute">@errors</span><span class="punct">=&lt;</span><span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Errors</span><span class="punct">:</span><span class="number">0x3938b18</span> <span class="punct">...&gt;,</span>
229
- <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"></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"></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"></span><span class="punct">&quot;},</span> <span class="attribute">@new_record</span><span class="punct">=</span><span class="constant">true</span><span class="punct">&gt;&gt;</span>
236
+ <span class="ident">person</span><span class="punct">.</span><span class="ident">errors</span>
237
+ <span class="punct">=&gt;</span> <span class="comment">#&lt;ActiveRecord::Errors:0x3537b38 @errors={</span>
238
+ <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>
239
+ <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>
240
+ <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>
241
+ <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>
242
+ <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>
230
243
  </pre></p>
231
244
 
232
245
 
233
- <p><strong>Kapoow!</strong> Instant validation!</p>
246
+ <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>
234
247
 
235
248
 
236
249
  <p>Because you specified the three columns as <code>:null =&gt; false</code>,
237
- your ActiveRecord models will now automatically generated <code>validates_presence_of</code>
238
- for each non-null field.</p>
250
+ your ActiveRecord models will now automagically generated <code>validates_presence_of</code>
251
+ for each non-null field, plus several other validations (since version 0.8.0).</p>
239
252
 
240
253
 
241
254
  <p>Ok, we&#8217;re just warming up.</p>
@@ -249,15 +262,15 @@ demonstrated above) to have the brilliantly simple support that Rails/ActiveReco
249
262
 
250
263
 
251
264
  <p><pre class="syntax">
252
- <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">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>
253
- <span class="punct">&gt;&gt;</span> <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>
254
- <span class="punct">&gt;&gt;</span> <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_id</span> <span class="punct">=&gt;</span> <span class="ident">person</span><span class="punct">,</span> <span class="symbol">:group_id</span> <span class="punct">=&gt;</span> <span class="ident">group</span><span class="punct">)</span>
255
- <span class="punct">&gt;&gt;</span> <span class="ident">person</span><span class="punct">.</span><span class="ident">memberships</span><span class="punct">.</span><span class="ident">length</span>
265
+ <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>
266
+ <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>
267
+ <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>
268
+ <span class="ident">person</span><span class="punct">.</span><span class="ident">memberships</span><span class="punct">.</span><span class="ident">length</span>
256
269
  <span class="punct">=&gt;</span> <span class="number">1</span>
257
- <span class="punct">&gt;&gt;</span> <span class="ident">membership</span><span class="punct">.</span><span class="ident">person</span>
270
+ <span class="ident">membership</span><span class="punct">.</span><span class="ident">person</span>
258
271
  <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>
259
272
  <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>
260
- <span class="punct">&gt;&gt;</span> <span class="ident">group</span><span class="punct">.</span><span class="ident">memberships</span>
273
+ <span class="ident">group</span><span class="punct">.</span><span class="ident">memberships</span>
261
274
  <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>
262
275
  </pre></p>
263
276
 
@@ -274,7 +287,7 @@ demonstrated above) to have the brilliantly simple support that Rails/ActiveReco
274
287
  </pre></p>
275
288
 
276
289
 
277
- <h2>Drum roll&#8230;</h2>
290
+ <h3>Drum roll&#8230;</h3>
278
291
 
279
292
 
280
293
  <p>Ladies and gentlemen. For my final feat of magical mastery, I&#8217;ll ask you to do
@@ -288,6 +301,8 @@ illusion that has been passed down through generations of magicians.</p>
288
301
  <span class="caps">DELETE</span> your three model classes: <code>person.rb, group.rb, and membership.rb</code> from the
289
302
  <code>app/models</code> folder. (You can always get them back via the model generator&#8230; be fearless!)
290
303
 
304
+ <pre>rm app/models/*.rb</pre>
305
+
291
306
  <p>Re-launch your console.</p>
292
307
 
293
308
 
@@ -307,9 +322,13 @@ illusion that has been passed down through generations of magicians.</p>
307
322
 
308
323
 
309
324
  <p><pre class="syntax">
325
+ <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>
326
+ <span class="punct">=&gt;</span> <span class="constant">false</span>
310
327
  <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>
311
328
  <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>
312
329
  <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>
330
+ <span class="punct">&gt;&gt;</span> <span class="ident">person</span><span class="punct">.</span><span class="ident">valid?</span>
331
+ <span class="punct">=&gt;</span> <span class="constant">true</span>
313
332
  <span class="punct">&gt;&gt;</span> <span class="ident">person</span><span class="punct">.</span><span class="ident">memberships</span>
314
333
  <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>
315
334
  <span class="punct">&gt;&gt;</span> <span class="ident">person</span><span class="punct">.</span><span class="ident">groups</span>
@@ -317,12 +336,26 @@ illusion that has been passed down through generations of magicians.</p>
317
336
  </pre></p>
318
337
 
319
338
 
320
- <h2>Tada!</h2>
339
+ <h3>Tada!</h3>
321
340
 
322
341
 
323
342
  <p>The end.</p>
324
343
 
325
344
 
345
+ <h3>Use modules to scope your magic</h3>
346
+
347
+
348
+ <p>Only want to pick up tables starting with <code>blog_</code>?</p>
349
+
350
+
351
+ <p><pre class="syntax"><span class="keyword">module </span><span class="module">Blog</span>
352
+ <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>
353
+ <span class="keyword">end</span>
354
+
355
+ <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>
356
+ </pre></p>
357
+
358
+
326
359
  <h2>Dr Nic&#8217;s Blog</h2>
327
360
 
328
361
 
@@ -357,7 +390,7 @@ other stories and things.</p>
357
390
  <p>Comments are welcome. Send an email to <a href="mailto:drnicwilliams@gmail.com">Dr Nic Williams</a>
358
391
  or via his blog at <a href="http://www.drnicwilliams.com">http://www.drnicwilliams.com</a></p>
359
392
  <p class="coda">
360
- <a href="mailto:drnicwilliams@gmail.com">Dr Nic</a>, 9th April 2007<br>
393
+ <a href="mailto:drnicwilliams@gmail.com">Dr Nic</a>, 11th April 2007<br>
361
394
  Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
362
395
  </p>
363
396
  </div>
data/website/index.txt CHANGED
@@ -66,10 +66,10 @@ Your application is now blessed with magical mystery.
66
66
 
67
67
  h2. David Copperfield eat your Ruby-crusted heart out
68
68
 
69
- Let's demonstrate the magical mystery in all its full-stage glory. Create a Ruby on Rails app:
69
+ Let'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):
70
70
 
71
71
  <pre syntax="ruby">
72
- rails magic_show
72
+ rails magic_show -d sqlite3
73
73
  cd magic_show
74
74
  ruby script/generate model Person
75
75
  ruby script/generate model Group
@@ -110,18 +110,12 @@ and <code>003_create_memberships.rb</code> with:
110
110
  end
111
111
  </pre>
112
112
 
113
- Now create your database. For MySql:
114
- <pre>
115
- mysqladmin -u root create magic_show_development
116
- mysqladmin -u root create magic_show_test
117
- </pre>
118
-
119
113
  And run your migrations to create the three tables:
120
114
  <pre>
121
- rake migrate
115
+ rake db:migrate
122
116
  </pre>
123
117
 
124
- h2. And now for some "woofle dust":http://en.wikipedia.org/wiki/List_of_conjuring_terms ...
118
+ h3. And now for some "woofle dust":http://en.wikipedia.org/wiki/List_of_conjuring_terms ...
125
119
 
126
120
  At the end of <code>config/environment.rb</code> add the following line:
127
121
 
@@ -142,6 +136,20 @@ end
142
136
 
143
137
  Nothing suspicious here. We have no validations and no associations. Just some plain old model classes.
144
138
 
139
+ UPDATE: To turn on magic validations, you now need to invoke <code>generate_validations</code> on defined classes. So, update your model classes:
140
+
141
+ <pre syntax="ruby">
142
+ class Person < ActiveRecord::Base
143
+ generate_validations
144
+ end
145
+ class Group < ActiveRecord::Base
146
+ generate_validations
147
+ end
148
+ class Membership < ActiveRecord::Base
149
+ generate_validations
150
+ end
151
+ </pre>
152
+
145
153
  For this trick, we'll need an ordinary console session. Any old one lying around the house will do.
146
154
 
147
155
  <pre>
@@ -152,22 +160,24 @@ Now a normal model class is valid until you explicitly add <code>validates_xxx</
152
160
  With Dr Nic's Magic Models:
153
161
 
154
162
  <pre syntax="ruby">
155
- >> person = Person.new
163
+ person = Person.new
156
164
  => #<Person:0x393e0f8 @attributes={"lastname"=>"", "firstname"=>"", "email"=>""}, @new_record=true>
157
- >> person.valid?
165
+ person.valid?
158
166
  => false
159
- >> person.errors
160
- => <ActiveRecord::Errors:0x3938b18 @errors={"firstname"=>["can't be blank"],
161
- "lastname"=>["can't be blank"], "email"=>["can't be blank"]},
162
- @base=<Person:0x393e0f8 @errors=<ActiveRecord::Errors:0x3938b18 ...>,
163
- @attributes={"lastname"=>"", "firstname"=>"", "email"=>""}, @new_record=true>>
167
+ person.errors
168
+ => #<ActiveRecord::Errors:0x3537b38 @errors={
169
+ "firstname"=>["can't be blank", "is too long (maximum is 255 characters)"],
170
+ "lastname"=>["can't be blank", "is too long (maximum is 255 characters)"],
171
+ "email"=>["can't be blank", "is too long (maximum is 255 characters)"]},
172
+ @base=#<Person:0x3538bf0 @errors=#<ActiveRecord::Errors:0x3537b38 ...>, @new_record=true,
173
+ @attributes={"lastname"=>nil, "firstname"=>nil, "email"=>nil}>>
164
174
  </pre>
165
175
 
166
- *Kapoow!* Instant validation!
176
+ *Kapoow!* Instant validation! (NOTE: not as instant as it used to be - remember - you need to call <code>generate_validations</code> on each class as required)
167
177
 
168
178
  Because you specified the three columns as <code>:null => false</code>,
169
- your ActiveRecord models will now automatically generated <code>validates_presence_of</code>
170
- for each non-null field.
179
+ your ActiveRecord models will now automagically generated <code>validates_presence_of</code>
180
+ for each non-null field, plus several other validations (since version 0.8.0).
171
181
 
172
182
  Ok, we're just warming up.
173
183
 
@@ -177,15 +187,15 @@ demonstrated above) to have the brilliantly simple support that Rails/ActiveReco
177
187
  Let's just watch what Dr Nic's Magic Models can do without any effort at all...
178
188
 
179
189
  <pre syntax="ruby">
180
- >> person = Person.create(:firstname => "Nic", :lastname => "Williams", :email => "drnicwilliams@gmail.com")
181
- >> group = Group.create(:name => "Magic Models Forum", :description => "http://groups.google.com/magicmodels")
182
- >> membership = Membership.create(:person_id => person, :group_id => group)
183
- >> person.memberships.length
190
+ person = Person.create(:firstname => "Nic", :lastname => "Williams", :email => "drnicwilliams@gmail.com")
191
+ group = Group.create(:name => "Magic Models Forum", :description => "http://groups.google.com/magicmodels")
192
+ membership = Membership.create(:person => person, :group => group)
193
+ person.memberships.length
184
194
  => 1
185
- >> membership.person
195
+ membership.person
186
196
  => <Person:0x38898e8 @attributes={"lastname"=>"Williams", "firstname"=>"Nic",
187
197
  "id"=>"1", "email"=>"drnicwilliams@gmail.com"}>
188
- >> group.memberships
198
+ group.memberships
189
199
  => [<Membership:0x3c8cd70 @attributes={"group_id"=>"1", "id"=>"1", "person_id"=>"1"}>]
190
200
  </pre>
191
201
 
@@ -200,7 +210,7 @@ The final association trick is a ripper. Automatic generation of <code>has_many
200
210
  "id"=>"1", "email"=>"drnicwilliams@gmail.com"}>]
201
211
  </pre>
202
212
 
203
- h2. Drum roll...
213
+ h3. Drum roll...
204
214
 
205
215
  Ladies and gentlemen. For my final feat of magical mastery, I'll ask you to do
206
216
  something you've never done before. This illusion is akin to the "floating lady":http://www.toytent.com/Posters/985.html
@@ -211,6 +221,8 @@ Exit your console session.
211
221
  DELETE your three model classes: <code>person.rb, group.rb, and membership.rb</code> from the
212
222
  <code>app/models</code> folder. (You can always get them back via the model generator... be fearless!)
213
223
 
224
+ <pre>rm app/models/*.rb</pre>
225
+
214
226
  Re-launch your console.
215
227
 
216
228
  *drums are still rolling...*
@@ -225,19 +237,34 @@ Be prepared to applaud loudly...
225
237
  You applaud loudly, but watch for more...
226
238
 
227
239
  <pre syntax="ruby">
240
+ >> Person.new.valid?
241
+ => false
228
242
  >> person = Person.find(1)
229
243
  => <Person:0x3958930 @attributes={"lastname"=>"Williams", "firstname"=>"Nic",
230
244
  "id"=>"1", "email"=>"drnicwilliams@gmail.com"}>
245
+ >> person.valid?
246
+ => true
231
247
  >> person.memberships
232
248
  => [<Membership:0x393a000 @attributes={"group_id"=>"1", "id"=>"1", "person_id"=>"1"}>]
233
249
  >> person.groups
234
250
  => [<Group:0x390df60 @attributes={"name"=>"Magic Models Forum", "id"=>"1", "description"=>nil}>]
235
251
  </pre>
236
252
 
237
- h2. Tada!
253
+ h3. Tada!
238
254
 
239
255
  The end.
240
256
 
257
+ h3. Use modules to scope your magic
258
+
259
+ Only want to pick up tables starting with <code>blog_</code>?
260
+
261
+ <pre syntax="ruby">module Blog
262
+ magic_module :table_name_prefix => 'blog_'
263
+ end
264
+
265
+ Blog::Post.table_name # => 'blog_posts'
266
+ </pre>
267
+
241
268
  h2. Dr Nic's Blog
242
269
 
243
270
  "http://www.drnicwilliams.com":http://www.drnicwilliams.com - for future announcements and
@@ -37,7 +37,7 @@ blockquote {
37
37
  }
38
38
 
39
39
  #main {
40
- width: 40em;
40
+ width: 55em;
41
41
  padding: 0;
42
42
  margin: 0 auto;
43
43
  }
@@ -32,12 +32,13 @@
32
32
  </head>
33
33
  <body>
34
34
  <div id="main">
35
+ <p><a href="/">&#x21A9; More Magic</a></p>
35
36
 
37
+ <div id="version" class="clickable" onclick='document.location = "<%= download %>"; return false'>
38
+ Get Version
39
+ <a id="version_num" href="<%= download %>" class="numbers"></a>
40
+ </div>
36
41
  <h1><%= title %></h1>
37
- <div id="version" class="clickable" onclick='document.location = "<%= download %>"; return false'>
38
- Get Version
39
- <a id="version_num" href="<%= download %>" class="numbers"></a>
40
- </div>
41
42
  <%= body %>
42
43
  <p class="coda">
43
44
  <a href="mailto:drnicwilliams@gmail.com">Dr Nic</a>, <%= modified.pretty %><br>
@@ -1,3 +1,3 @@
1
1
  // Version JS file
2
- var version = "0.9.0";
2
+ var version = "0.9.1";
3
3
  MagicAnnouncement.show('magicmodels', version);
data/website/version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  // Version JS file
2
- var version = "0.9.0";
2
+ var version = "0.9.1";
3
3
 
4
4
  document.write(" - " + version);
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.2
3
3
  specification_version: 1
4
4
  name: dr_nic_magic_models
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.9.0
7
- date: 2007-04-09 00:00:00 +02:00
6
+ version: 0.9.1
7
+ date: 2007-04-11 00:00:00 +02:00
8
8
  summary: Dr Nic's Magic Models - Invisible validations, assocations and Active Record models themselves!
9
9
  require_paths:
10
10
  - lib
@@ -74,6 +74,7 @@ files:
74
74
  - test/invisible_model_assoc_test.rb
75
75
  - test/invisible_model_classes_test.rb
76
76
  - test/magic_module_test.rb
77
+ - test/test_existing_model.rb
77
78
  - website/index.html
78
79
  - website/index.txt
79
80
  - website/javascripts/rounded_corners_lite.inc.js
@@ -84,8 +85,8 @@ files:
84
85
  - website/version-raw.txt
85
86
  - website/version.js
86
87
  - website/version.txt
87
- test_files: []
88
-
88
+ test_files:
89
+ - test/test_existing_model.rb
89
90
  rdoc_options: []
90
91
 
91
92
  extra_rdoc_files: []