Ruby Forum Ruby on Rails > [ANN] Dr Nicâ??s Magic Models

Posted by Dr Nic (nicwilliams)
on 07.08.2006 22:57
Welcome! Welcome! Welcome! Ladies and Gentlemen, today you shall be 
thrilled and dazzled by wonders of magical mystery.

Dr Nicâ??s Magic Models will now be unveiled to all. Mystery and magic 
that you will be able to perform at home.

Within your ActiveRecord models, never again will you need to write:

    * validates_presence_of validations
    * has_many and belongs_to statements
    * has_many :through statements!!

And for the finale, you will be amazed and astounded as you watch 
ActiveRecord models appear from nowhere. No class definition, just any 
old database tables you have lying around the home is all youâ??ll need to 
perform this trick!

No cover charge. No free steak knives. No heavy lifting involved.

Installation, DIY magical instructions, and a world of mystery awaits 
you at:
http://magicmodels.rubyforge.org

Dr Nic: http://drnicwilliams.com
Posted by Joe (Guest)
on 07.08.2006 23:19
Wow, that looks pretty damn awesome! Right now, adding all the 
validates, habtm, hm, etc. usually takes me a bit more time than I'd 
care to spend. Having it all be automatic would be cool. It looks like 
your plugin also automatically handles belongs_to -- how about has_one?

Joe
Posted by Dr Nic (nicwilliams)
on 07.08.2006 23:21
Joe wrote:
> Wow, that looks pretty damn awesome! Right now, adding all the 
> validates, habtm, hm, etc. usually takes me a bit more time than I'd 
> care to spend. Having it all be automatic would be cool. It looks like 
> your plugin also automatically handles belongs_to -- how about has_one?
> 
> Joe

Oooh. I forgot to write up that one. Let's make it a secret feature!

In the case of the example on the website, if you did:

person = Person.find_first
person.memberships
=> list of Memberships

person.membership
=> :first item of Memberships list

So you get both for free based on which method name you call.
Posted by Dr Nic (nicwilliams)
on 08.08.2006 06:52
> http://magicmodels.rubyforge.org

BTW, an extension will come out in future for the Magic Models to work 
with the Composite Primary Keys solution.

Cheers
Nic
Posted by Hammed Malik (Guest)
on 08.08.2006 07:13
(Received via mailing list)
Hi Dr. Nic!

This looks very interesting. I'll try it after work today. I'm curious 
to
see how it works with the Dry Scaffold announced recently.

Some questions:

Are there any performance penalities associated with all this magic? Is 
all
this introspection done once or with each request?

If any relationships are defined, does magic models respect them?

Hammed
Posted by Dr Nic (nicwilliams)
on 08.08.2006 07:19
> This looks very interesting. I'll try it after work today. I'm curious 
> to
> see how it works with the Dry Scaffold announced recently.

Do you have a URL for that?

> Some questions:
> 
> Are there any performance penalities associated with all this magic? Is 
> all
> this introspection done once or with each request?
> 
> If any relationships are defined, does magic models respect them?

It uses lazy evaluation - if you send "groups" to a Person object, and 
that method doesn't exist already (ie. you haven't already defined the 
has_many :groups, :through => :memberships association), then it will 
build that assocation for you - just as if you'd done it manually in 
your class definition. Once. Then the method will be there next time.

The only additional performance overhead is the one-time collection of 
some table and column meta-data via the connection object.

The class creation is similar - if you ask for a constant that doesn't 
exist, e.g. Person, then it will look through the table model for a 
table that might match such a class name, e.g. people, and build the 
class on top of it. Next time you ask for that class, its already built. 
Again, its a one-time meta-data request to database.

Ruby is wonderful :)
Posted by Hammed Malik (Guest)
on 08.08.2006 07:28
(Received via mailing list)
DRY Scaffold: http://dry.rubyforge.org/

Good to know about the low overhead. Looking forward to trying it out.
Posted by Dr Nic (nicwilliams)
on 08.08.2006 07:44
Hammed Malik wrote:
> DRY Scaffold: http://dry.rubyforge.org/
> 
> Good to know about the low overhead. Looking forward to trying it out.

I'll have a play with the Dry Scaffold (which looks very similar to the 
www.ajaxscaffold.com solution) and find out how it reflectively 
determines the associations.
Posted by Nathaniel Brown (nshb)
on 08.08.2006 08:50
(Received via mailing list)
Haha, I love magic tricks!

Very nice trick Dr. Nic! Very nice trick indeed.

I am very curious on how much of an cost impact this incurs compared to 
the
vanilla AR, but truth be told, it can be made up elsewhere. A Benchmark
would be nice to see how much it does impact it though :)

Definately will be keeping an eye on this project. Congrats.

-NSHB

On 8/7/06, Dr Nic <drnicwilliams@gmail.com> wrote:
> --
> Posted via http://www.ruby-forum.com/.
> _______________________________________________
> Rails mailing list
> Rails@lists.rubyonrails.org
> http://lists.rubyonrails.org/mailman/listinfo/rails
>



--
Kind regards,

Nathaniel Brown
President & CEO
Inimit Innovations Inc. - http://inimit.com
Posted by Dr Nic (nicwilliams)
on 08.08.2006 09:22
Nathaniel Brown wrote:
> Haha, I love magic tricks!

I used to know a couple good card tricks and even a routine using sponge 
balls. But I wasn't very diligent at practising :)

> Very nice trick Dr. Nic! Very nice trick indeed.
> 
> I am very curious on how much of an cost impact this incurs compared to 
> the
> vanilla AR, but truth be told, it can be made up elsewhere. A Benchmark
> would be nice to see how much it does impact it though :)

I really don't think there's a significant performance impact - the 
first time the association is requested it is created. From then on, its 
regular schedule programming.

There's more "How it works" for you here:
http://drnicwilliams.com/2006/08/07/ann-dr-nics-magic-models/#comments

Cheers
Nic
Posted by Chris (Guest)
on 08.08.2006 11:15
Dr Nic wrote:
> Welcome! Welcome! Welcome! Ladies and Gentlemen, today you shall be 
> thrilled and dazzled by wonders of magical mystery.
> 

Wow! This is an amazing achievement, having been writing models 
exclusively
yesterday, most of it repeat typing validates_presence_of and has_many
:through, this is friggin' awesome!!

Though I do fear that if Rails keeps innovating and improving at this
rate there's gonna very little for us programmers to do!

Fantastic work Dr Nic (and I love the presentation, I'm a sucker for
magic tricks!)
Posted by Michael Siebert (Guest)
on 08.08.2006 11:32
(Received via mailing list)
Nic,
thats great, im gonna test it... does it care about maximum length too?
there's so much in our models were we weren't DRY, e.g. the presence,
maximum length, even format of a field (number, date, datetime etc)
is that already in your gem or can it be done for next release?


2006/8/7, Dr Nic <drnicwilliams@gmail.com>:
>    * has_many and belongs_to statements
> you at:
>
--
Michael Siebert <info@siebert-wd.de>

www.stellar-legends.de - Weltraum-Browsergame im Alpha-Stadium
Posted by Dr Nic (nicwilliams)
on 08.08.2006 11:41
Chris wrote:
> Dr Nic wrote:
>> Welcome! Welcome! Welcome! Ladies and Gentlemen, today you shall be 
>> thrilled and dazzled by wonders of magical mystery.
>> 
> 
> Wow! This is an amazing achievement, having been writing models 
> exclusively
> yesterday, most of it repeat typing validates_presence_of and has_many
> :through, this is friggin' awesome!!

Sorry I didn't release it a day earlier... :( I just couldn't find time 
to write the website for it. But I did fix a bug in it whilst writing 
the tutorial/magic show. So that's a bonus :)

> Though I do fear that if Rails keeps innovating and improving at this
> rate there's gonna very little for us programmers to do!

We read blogs and forums to keep up-to-date with all the time saving 
tricks and tools that are available!

> Fantastic work Dr Nic (and I love the presentation, I'm a sucker for
> magic tricks!)

I'm loving the AdSense on this thread:

* Must-See New Blender
* Magic Bullet
* Coin Trick
* Learn David Blaine Magic
Posted by Dr Nic (nicwilliams)
on 08.08.2006 12:31
Michael Siebert wrote:
> Nic,
> thats great, im gonna test it... does it care about maximum length too?
> there's so much in our models were we weren't DRY, e.g. the presence,
> maximum length, even format of a field (number, date, datetime etc)
> is that already in your gem or can it be done for next release?

It has all the same support/limitations that ActiveRecord 
Associations/Validations have now.

If your old model class looked like:

  class Account < ActiveRecord::Base
    has_many :charges
    belongs_to :user
    validates_presence_of :initial_balance
  end

and that worked for you, then you can replace it with:

  class Account < ActiveRecord::Base
  end

If you had more complicated has_many/belongs_to associations, or if you 
used additional validations, then you'll need to add those manually as 
usual.

"DRY" - I should have used that in the magic show somehow...

Cheers
Nic
Posted by Stuart Fellowes (zanoni)
on 08.08.2006 12:44
(Received via mailing list)
Can I use it with existing schemas ?

Stuart
Posted by Dr Nic (nicwilliams)
on 08.08.2006 12:53
Stuart Fellowes wrote:
> Can I use it with existing schemas ?

Yes.

I actually conceived the idea of auto-generating the ActiveRecord 
classes first, of all the features in the Magic Models, because I was 
faced with a legacy database with 50+ tables in it. I'd rather spend two 
days writing something like the Magic Models gem than spend one day 
knuckling down and doing it the manual way :)

Magic Models don't currently work with Composite Primary Keys but I'll 
extend MM to do so in the future. Subscribe to the blog 
(http://drnicwilliams.com) for an announcement.

Cheers
Nic
Posted by J Amiel (Guest)
on 08.08.2006 16:09
I'm not sure whether to be appalled or elated over this trickery.

One of the biggest complaints I hear about the rails naysayers is the 
inability to look at the model class (a la ActiveRecord) and be able to 
determine what fields it contains (forcing you to have to look in the 
database schema) when doing your development.

So, prior to Dr Nic's Magic models, you would have TWO places to look 
for model information -   the model class def (to see relationships and 
validation rules) and the database schema for everything else.

Now (in certain circumstances), EVERYTHING can be found in the schema. 
Something neat (and scary) about that.

At the very least, it's a super-neat trick.
At the most, it's yet ANOTHER way to DRY by using convention over 
configuration.  If you are already setting limits in the schema (not 
null, length, etc), why repeat it in your model?

Huh.

I don't know if I can force myself to take my hand off the 'railing' and 
say, "look ma, no models!".....but I am overjoyed at the option.




Posted by Dr Nic (nicwilliams)
on 08.08.2006 16:24
J Amiel wrote:
> I'm not sure whether to be appalled or elated over this trickery.

A: Elated. Glad I could help answer that one for you :)

Oh and its not "trickery" its "magic"! Where you say, "tada!" at the 
end.

> One of the biggest complaints I hear about the rails naysayers is the 
> inability to look at the model class (a la ActiveRecord) and be able to 
> determine what fields it contains (forcing you to have to look in the 
> database schema) when doing your development.

You can get the columns of the underlying table via @obj.columns 
/@obj.class.columns; if that helps.

> So, prior to Dr Nic's Magic models, you would have TWO places to look 
> for model information -   the model class def (to see relationships and 
> validation rules) and the database schema for everything else.
> 
> Now (in certain circumstances), EVERYTHING can be found in the schema. 
> Something neat (and scary) about that.

It's only a pity that there isn't MORE meta-data that can be found via 
the current ActiveRecord API. It's limited by a "lowest-common 
denominator" approach ; for example, you cannot discover any foreign 
keys.

> At the very least, it's a super-neat trick.
> At the most, it's yet ANOTHER way to DRY by using convention over 
> configuration.  If you are already setting limits in the schema (not 
> null, length, etc), why repeat it in your model?

Oooh. Hadn't thought of a validation of length... Nice one. I think 
someone else mentioned length before, but I hadn't thought of generating 
a validation for it.

> I don't know if I can force myself to take my hand off the 'railing' and 
> say, "look ma, no models!".....but I am overjoyed at the option.

I think you'll quickly need your models if you want to add methods and 
specific associations. Plus with something like the annotate_models 
plugin, you can generate a comment header to show you the schema 
definition.

With the exception of the validations which you currently cannot turn 
off (if the column is not-null, then you get a validates_presence_of) 
all the other features are still optional as required by the developer 
(if you don't want an association generated... don't call the method!)

It all works on the assumption that if you call a method on an object 
then the object assumes you were looking for something and tries to 
help. The logic of Magic Models is, If no method currently exists 
"perhaps he wanted an association to another table?" If it can generate 
an association for you, it will, and will return the result. Else it 
will return the normal error for missing method.

Cheers
Nic
Posted by Xavier Noria (Guest)
on 08.08.2006 17:30
(Received via mailing list)
On Aug 8, 2006, at 4:09 PM, J Amiel wrote:

> One of the biggest complaints I hear about the rails naysayers is the
> inability to look at the model class (a la ActiveRecord) and be  
> able to
> determine what fields it contains (forcing you to have to look in the
> database schema) when doing your development.

This is simple and handy:

   annotate_models
   http://plugins.radrails.org/directory/show/12

For visualization there's this

   Visualize Models
   http://visualizemodels.rubyforge.org/

-- fxn
Posted by Michael Siebert (Guest)
on 08.08.2006 17:48
(Received via mailing list)
2006/8/8, Dr Nic <drnicwilliams@gmail.com>:

> Oooh. Hadn't thought of a validation of length... Nice one. I think
> someone else mentioned length before, but I hadn't thought of generating
> a validation for it.


thats exactly what i wanted to say. just DRY


--
Michael Siebert <info@siebert-wd.de>

www.stellar-legends.de - Weltraum-Browsergame im Alpha-Stadium
Posted by Michael Siebert (Guest)
on 08.08.2006 17:48
(Received via mailing list)
2006/8/8, Xavier Noria <fxn@hashref.com>:
>
> This is simple and handy:
>
>    annotate_models
>    http://plugins.radrails.org/directory/show/12
>
> For visualization there's this
>
>    Visualize Models
>    http://visualizemodels.rubyforge.org/


do they work when i dont have ANY model file?




--
Michael Siebert <info@siebert-wd.de>

www.stellar-legends.de - Weltraum-Browsergame im Alpha-Stadium
Posted by Dr Nic (nicwilliams)
on 08.08.2006 18:17
Michael Siebert wrote:
> 2006/8/8, Xavier Noria <fxn@hashref.com>:
>>
>> This is simple and handy:
>>
>>    annotate_models
>>    http://plugins.radrails.org/directory/show/12
>>
>> For visualization there's this
>>
>>    Visualize Models
>>    http://visualizemodels.rubyforge.org/
> 
> 
> do they work when i dont have ANY model file?

The latter seems to only use models in the apps/models folder and 
derives its associations itself, rather than using has_many/belongs_to 
if defined.

Similarly for the former - no point annotating a model file if you don't 
have one :)

But as an aside, after chatting with a few people, the next release will 
include a class method on ActiveRecord::Base called 
'generate_all_classes' (for situations where you need all your models 
and their associations now).

Cheers
Nic
Posted by Xavier Noria (Guest)
on 08.08.2006 18:36
(Received via mailing list)
On Aug 8, 2006, at 5:46 PM, Michael Siebert wrote:

>
> do they work when i dont have ANY model file?

The diagram for an empty model set is the empty canvas by definition!
Oh well, unless there's some magic going on, yeah umh.

-- fxn
Posted by Joe Ruby (Guest)
on 08.08.2006 20:59
Dr. Nic -

Think it's possible to get constraint info from the database and figure 
out additional validates_* from that? I don't know if MySQL even has 
contraints yet, but with PostgreSQL you can specify things like 'check 
age > 0 and age < 150', etc. Another idea is that columns with unique 
constraints could also translate into validates_uniqueness_of. Just a 
couple ideas if you want to get crazy. ;)

Joe
Posted by Dr Nic (nicwilliams)
on 08.08.2006 21:05
> Think it's possible to get constraint info from the database and figure 
> out additional validates_* from that? I don't know if MySQL even has 
> contraints yet, but with PostgreSQL you can specify things like 'check 
> age > 0 and age < 150', etc. Another idea is that columns with unique 
> constraints could also translate into validates_uniqueness_of. Just a 
> couple ideas if you want to get crazy. ;)

Someone pointed me to 
http://www.redhillconsulting.com.au/blogs/simon/archives/000339.html 
where Simon has some more code ideas on generating validations based on 
the schema data that is available through the current ActiveRecord API.

Adding these will be the first upgrade to the validation generation.

Using database-type-specific meta-data might be difficult until there is 
an API for exposing the data first. Not impossible - merely not my area 
of expertise at the moment.

Cheers
Nic
Posted by John W. Long (Guest)
on 09.08.2006 15:07
(Received via mailing list)
Dr Nic wrote:
> Dr Nicâ??s Magic Models will now be unveiled to all. Mystery and magic 
> that you will be able to perform at home.

I would love to see a console app distributed with this so that I could
do something like:

% drnic --mysql -d my_active_record_db -u username -p password

And instantly be in an IRB session with whatever database I chose.

--
John Long
http://wiseheartdesign.com
http://radiantcms.org
Posted by Dr Nic (nicwilliams)
on 09.08.2006 15:15
>> Dr Nicâ??s Magic Models will now be unveiled to all. Mystery and magic 
>> that you will be able to perform at home.
> 
> I would love to see a console app distributed with this so that I could
> do something like:
> 
> % drnic --mysql -d my_active_record_db -u username -p password
> 
> And instantly be in an IRB session with whatever database I chose.

Two things:
i) That should be possible.
ii) My ego wouldn't allow it to be called 'drnic' :)

The dynamic construction of the connection parameters from the arguments 
might be difficult (read: I don't know how I'd do that generically for 
all DBs). Does anyone have/know-of a similar Ruby app that takes 
connection parameters via the application arguments?

Definitely a good idea, John.
Posted by James Mead (floehopper)
on 15.08.2006 14:18
(Received via mailing list)
On 08/08/06, Dr Nic <drnicwilliams@gmail.com> wrote:
> I think you'll quickly need your models if you want to add methods and
> specific associations. Plus with something like the annotate_models
> plugin, you can generate a comment header to show you the schema
> definition.

If you use TextMate, you might like to try Chris Roos' command which
displays the table structure in a tooltip -
http://blog.seagul.co.uk/articles/2006/07/14/textmate-command-to-display-active-record-column-attributes.
I think it's now been incorporated into the TextMate rails bundle.
Posted by Dr Nic (nicwilliams)
on 15.08.2006 16:54
James Mead wrote:
> On 08/08/06, Dr Nic <drnicwilliams@gmail.com> wrote:
>> I think you'll quickly need your models if you want to add methods and
>> specific associations. Plus with something like the annotate_models
>> plugin, you can generate a comment header to show you the schema
>> definition.
> 
> If you use TextMate, you might like to try Chris Roos' command which
> displays the table structure in a tooltip -
> http://blog.seagul.co.uk/articles/2006/07/14/textmate-command-to-display-active-record-column-attributes.
> I think it's now been incorporated into the TextMate rails bundle.

That's sexy - I think its definitely a good idea for Rails-specific IDEs 
to allow Model -> Schema view -> Model transition hot keys.

I use RadRails and it supports Model -> Unit Test -> Model windows via 
Shift-Ctrl-V. Perhaps I'll see I can get them to add a Model -> Schema 
View -> Model transitions on Shift-Ctrl-S or something.