dr_nic_magic_models 0.9.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +10 -1
- data/Manifest.txt +1 -0
- data/README +55 -29
- data/lib/dr_nic_magic_models/magic_model.rb +4 -2
- data/lib/dr_nic_magic_models/version.rb +1 -1
- data/lib/dr_nic_magic_models.rb +4 -1
- data/lib/module.rb +5 -5
- data/test/magic_module_test.rb +1 -1
- data/test/test_existing_model.rb +20 -0
- data/test.db +0 -0
- data/website/index.html +66 -33
- data/website/index.txt +55 -28
- data/website/stylesheets/screen.css +1 -1
- data/website/template.rhtml +5 -4
- data/website/version-raw.js +1 -1
- data/website/version.js +1 -1
- metadata +5 -4
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
|
-
|
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
|
-
|
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
|
-
|
166
|
+
person = Person.new
|
160
167
|
=> #<Person:0x393e0f8 @attributes={"lastname"=>"", "firstname"=>"", "email"=>""}, @new_record=true>
|
161
|
-
|
168
|
+
person.valid?
|
162
169
|
=> false
|
163
|
-
|
164
|
-
=>
|
165
|
-
"
|
166
|
-
|
167
|
-
|
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
|
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
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
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
|
-
|
198
|
+
membership.person
|
190
199
|
=> <Person:0x38898e8 @attributes={"lastname"=>"Williams", "firstname"=>"Nic",
|
191
200
|
"id"=>"1", "email"=>"drnicwilliams@gmail.com"}>
|
192
|
-
|
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
|
-
|
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
|
-
|
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
|
56
|
+
if !fkc.nil? && fkc.length > 0
|
57
57
|
foreign_key = fkc.first.foreign_key
|
58
|
-
options = {:dependent => :destroy,
|
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
|
data/lib/dr_nic_magic_models.rb
CHANGED
@@ -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(
|
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
|
-
|
31
|
+
self.const_set class_name, klass
|
32
32
|
end
|
33
33
|
end
|
data/test/magic_module_test.rb
CHANGED
@@ -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="/">↩ 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’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’ve used Ruby on Rails you’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’s demonstrate the magical mystery in all its full-stage glory. Create a Ruby on Rails app:</p>
|
124
|
+
<p>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):</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
|
-
<
|
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"><</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"><</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"><</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’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’s Magic Models:</p>
|
|
218
229
|
|
219
230
|
|
220
231
|
<p><pre class="syntax">
|
221
|
-
<span class="
|
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">=></span> <span class="comment">#<Person:0x393e0f8 @attributes={"lastname"=>"", "firstname"=>"", "email"=>""}, @new_record=true></span>
|
223
|
-
<span class="
|
234
|
+
<span class="ident">person</span><span class="punct">.</span><span class="ident">valid?</span>
|
224
235
|
<span class="punct">=></span> <span class="constant">false</span>
|
225
|
-
<span class="
|
226
|
-
<span class="punct">=></span> <span class="
|
227
|
-
<span class="punct">"</span><span class="string">
|
228
|
-
<span class="
|
229
|
-
<span class="
|
236
|
+
<span class="ident">person</span><span class="punct">.</span><span class="ident">errors</span>
|
237
|
+
<span class="punct">=></span> <span class="comment">#<ActiveRecord::Errors:0x3537b38 @errors={</span>
|
238
|
+
<span class="punct">"</span><span class="string">firstname</span><span class="punct">"=>["</span><span class="string">can't be blank</span><span class="punct">",</span> <span class="punct">"</span><span class="string">is too long (maximum is 255 characters)</span><span class="punct">"],</span>
|
239
|
+
<span class="punct">"</span><span class="string">lastname</span><span class="punct">"=>["</span><span class="string">can't be blank</span><span class="punct">",</span> <span class="punct">"</span><span class="string">is too long (maximum is 255 characters)</span><span class="punct">"],</span>
|
240
|
+
<span class="punct">"</span><span class="string">email</span><span class="punct">"=>["</span><span class="string">can't be blank</span><span class="punct">",</span> <span class="punct">"</span><span class="string">is too long (maximum is 255 characters)</span><span class="punct">"]},</span>
|
241
|
+
<span class="attribute">@base</span><span class="punct">=</span><span class="comment">#<Person:0x3538bf0 @errors=#<ActiveRecord::Errors:0x3537b38 ...>, @new_record=true, </span>
|
242
|
+
<span class="attribute">@attributes</span><span class="punct">={"</span><span class="string">lastname</span><span class="punct">"=></span><span class="constant">nil</span><span class="punct">,</span> <span class="punct">"</span><span class="string">firstname</span><span class="punct">"=></span><span class="constant">nil</span><span class="punct">,</span> <span class="punct">"</span><span class="string">email</span><span class="punct">"=></span><span class="constant">nil</span><span class="punct">}>></span>
|
230
243
|
</pre></p>
|
231
244
|
|
232
245
|
|
233
|
-
<p><strong>Kapoow!</strong> Instant validation
|
246
|
+
<p><strong>Kapoow!</strong> 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)</p>
|
234
247
|
|
235
248
|
|
236
249
|
<p>Because you specified the three columns as <code>:null => false</code>,
|
237
|
-
your ActiveRecord models will now
|
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’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="
|
253
|
-
<span class="
|
254
|
-
<span class="
|
255
|
-
<span class="
|
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">=></span> <span class="punct">"</span><span class="string">Nic</span><span class="punct">",</span> <span class="symbol">:lastname</span> <span class="punct">=></span> <span class="punct">"</span><span class="string">Williams</span><span class="punct">",</span> <span class="symbol">:email</span> <span class="punct">=></span> <span class="punct">"</span><span class="string">drnicwilliams@gmail.com</span><span class="punct">")</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">=></span> <span class="punct">"</span><span class="string">Magic Models Forum</span><span class="punct">",</span> <span class="symbol">:description</span> <span class="punct">=></span> <span class="punct">"</span><span class="string">http://groups.google.com/magicmodels</span><span class="punct">")</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">=></span> <span class="ident">person</span><span class="punct">,</span> <span class="symbol">:group</span> <span class="punct">=></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">=></span> <span class="number">1</span>
|
257
|
-
<span class="
|
270
|
+
<span class="ident">membership</span><span class="punct">.</span><span class="ident">person</span>
|
258
271
|
<span class="punct">=></span> <span class="punct"><</span><span class="constant">Person</span><span class="punct">:</span><span class="number">0x38898e8</span> <span class="attribute">@attributes</span><span class="punct">={"</span><span class="string">lastname</span><span class="punct">"=>"</span><span class="string">Williams</span><span class="punct">",</span> <span class="punct">"</span><span class="string">firstname</span><span class="punct">"=>"</span><span class="string">Nic</span><span class="punct">",</span>
|
259
272
|
<span class="punct">"</span><span class="string">id</span><span class="punct">"=>"</span><span class="string">1</span><span class="punct">",</span> <span class="punct">"</span><span class="string">email</span><span class="punct">"=>"</span><span class="string">drnicwilliams@gmail.com</span><span class="punct">"}></span>
|
260
|
-
<span class="
|
273
|
+
<span class="ident">group</span><span class="punct">.</span><span class="ident">memberships</span>
|
261
274
|
<span class="punct">=></span> <span class="punct">[<</span><span class="constant">Membership</span><span class="punct">:</span><span class="number">0x3c8cd70</span> <span class="attribute">@attributes</span><span class="punct">={"</span><span class="string">group_id</span><span class="punct">"=>"</span><span class="string">1</span><span class="punct">",</span> <span class="punct">"</span><span class="string">id</span><span class="punct">"=>"</span><span class="string">1</span><span class="punct">",</span> <span class="punct">"</span><span class="string">person_id</span><span class="punct">"=>"</span><span class="string">1</span><span class="punct">"}>]</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
|
-
<
|
290
|
+
<h3>Drum roll…</h3>
|
278
291
|
|
279
292
|
|
280
293
|
<p>Ladies and gentlemen. For my final feat of magical mastery, I’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… 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">>></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">=></span> <span class="constant">false</span>
|
310
327
|
<span class="punct">>></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">=></span> <span class="punct"><</span><span class="constant">Person</span><span class="punct">:</span><span class="number">0x3958930</span> <span class="attribute">@attributes</span><span class="punct">={"</span><span class="string">lastname</span><span class="punct">"=>"</span><span class="string">Williams</span><span class="punct">",</span> <span class="punct">"</span><span class="string">firstname</span><span class="punct">"=>"</span><span class="string">Nic</span><span class="punct">",</span>
|
312
329
|
<span class="punct">"</span><span class="string">id</span><span class="punct">"=>"</span><span class="string">1</span><span class="punct">",</span> <span class="punct">"</span><span class="string">email</span><span class="punct">"=>"</span><span class="string">drnicwilliams@gmail.com</span><span class="punct">"}></span>
|
330
|
+
<span class="punct">>></span> <span class="ident">person</span><span class="punct">.</span><span class="ident">valid?</span>
|
331
|
+
<span class="punct">=></span> <span class="constant">true</span>
|
313
332
|
<span class="punct">>></span> <span class="ident">person</span><span class="punct">.</span><span class="ident">memberships</span>
|
314
333
|
<span class="punct">=></span> <span class="punct">[<</span><span class="constant">Membership</span><span class="punct">:</span><span class="number">0x393a000</span> <span class="attribute">@attributes</span><span class="punct">={"</span><span class="string">group_id</span><span class="punct">"=>"</span><span class="string">1</span><span class="punct">",</span> <span class="punct">"</span><span class="string">id</span><span class="punct">"=>"</span><span class="string">1</span><span class="punct">",</span> <span class="punct">"</span><span class="string">person_id</span><span class="punct">"=>"</span><span class="string">1</span><span class="punct">"}>]</span>
|
315
334
|
<span class="punct">>></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
|
-
<
|
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">=></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"># => 'blog_posts'</span>
|
356
|
+
</pre></p>
|
357
|
+
|
358
|
+
|
326
359
|
<h2>Dr Nic’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>,
|
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
|
-
|
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
|
-
|
163
|
+
person = Person.new
|
156
164
|
=> #<Person:0x393e0f8 @attributes={"lastname"=>"", "firstname"=>"", "email"=>""}, @new_record=true>
|
157
|
-
|
165
|
+
person.valid?
|
158
166
|
=> false
|
159
|
-
|
160
|
-
=>
|
161
|
-
"
|
162
|
-
|
163
|
-
|
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
|
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
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
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
|
-
|
195
|
+
membership.person
|
186
196
|
=> <Person:0x38898e8 @attributes={"lastname"=>"Williams", "firstname"=>"Nic",
|
187
197
|
"id"=>"1", "email"=>"drnicwilliams@gmail.com"}>
|
188
|
-
|
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
|
-
|
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
|
-
|
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
|
data/website/template.rhtml
CHANGED
@@ -32,12 +32,13 @@
|
|
32
32
|
</head>
|
33
33
|
<body>
|
34
34
|
<div id="main">
|
35
|
+
<p><a href="/">↩ 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>
|
data/website/version-raw.js
CHANGED
data/website/version.js
CHANGED
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.
|
7
|
-
date: 2007-04-
|
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: []
|